纯净、安全、绿色的下载网站

首页|软件分类|下载排行|最新软件|IT学院

当前位置:首页IT学院IT技术

C++ char*不能修改 C++中char[]能修改char*却不行

薄荷醇   2021-09-13 我要评论
想了解C++中char[]能修改char*却不行的相关内容吗,薄荷醇在本文为您仔细讲解C++ char*不能修改的相关知识和一些Code实例,欢迎阅读和指正,我们先划重点:C++,char*不能修改,C++,char[]能修改char*却不行,下面大家一起来学习吧。

少扯淡没用的,直接上代码

int main(int argc, char *argv[])
{
	char p[74] = "abcefghijkmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm";
	char *a = "abcefghijkmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm";
	printf("%s,%s",p,a);
}

这谁都能看明白,最终输出两次abcefghijkmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm,没问题
把代码再改改

int main(int argc, char *argv[])
{
	char p[74] = "abcefghijkmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm";
	char *a = "abcefghijkmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm";
	p[8]= 'd';
	a[8] = 'd';
	//printf("%s,%s",p,a);
}

运行,报错

在这里插入图片描述

错误指向了a[8] = ‘d'

在这里插入图片描述

错误指向第12行,为嘛尼?

看汇编

在这里插入图片描述

可以看到变量p,和a 都是采用了同样的方式

d使用了

mov  esi,offset string "abcefghijkmmmmmmmmmmmmmmmmmmmmmm"...

将字符串的偏移地址,赋值到esi寄存器

a使用了

mov dword ptr [a],offset string "abcefghijkmmmmmmmmmmmmmmmmmmmmmm"...

将字符串的偏移地址,赋值到a变量所在地址

仔细看图 这两句对字符串的取址操作,来源都是一个地方,01007500h,也就是程序数据段在内存中的位置

在这里插入图片描述

既然两个操作都是对同一个字符串的操作,为什么有的可以修改,有的不行?

这里面有个关于编译文件后程序的存储问题,如上例

变量a,p他们都是操作相同的字符串,两个字符串完全相同,所以,程序编译后,生成的文件内,完全没有必要保存两个相同的内容,只保留一个便可以,所以,你的程序,不管多少次使用这个字符串,实际上都是从一个地方引用的,这就是,这两句代码

mov  esi,offset string "abcefghijkmmmmmmmmmmmmmmmmmmmmmm"...
mov dword ptr [a],offset string "abcefghijkmmmmmmmmmmmmmmmmmmmmmm"...

的意思。

但这就出现了一个问题,如果两个或者多个变量都用了同一个字符串,然后最终要的,还进行了修改,结果就是,所有引用这个字符串的变量,都变了,所以

a[8] = 'd';

要直接修改数据段,就报错了

但是p可以,为什么,应为数组的处理是不一样的,看代码

mov         esi,offset string "abcefghijkmmmmmmmmmmmmmmmmmmmmmm"... (0977588h)  
lea         edi,[p]  
rep movs    dword ptr es:[edi],dword ptr [esi]  

首先,把字符串的地址给了esi,然后把p地址给了edi,
然后,通过rep movs 循环执行,吧[esi]处的字符,赋值给[edi],也就是把字符串复制一份到p

所以,你操作的

p[8] ='d';

实事上是操作了一个新的字符串,不是数据段中的那个字符串,

再看关于a的操作

mov       dword ptr [a],offset string "abcefghijkmmmmmmmmmmmmmmmmmmmmmm"...
mov       eax,1  
shl       eax,3  
mov       ecx,dword ptr [a]  
mov       byte ptr [ecx+eax],64h 

首先把1给了eax,然后执行位移3,把EAX,变成8,把a的地址,也就是字符串的地址给了ecx,然后吧64h也就是d,赋值给[ecx+eax] 那个位置,也就是j的位置,因而你操作的是数据段中的那个字符串,就是上面的原因,系统会阻止你修改数据段,因而报错


相关文章

猜您喜欢

  • Java之包和继承 Java语言之包和继承详解

    想了解Java语言之包和继承详解的相关内容吗,飞人01_01在本文为您仔细讲解Java之包和继承的相关知识和一些Code实例,欢迎阅读和指正,我们先划重点:Java包,Java继承,下面大家一起来学习吧。..
  • vue上传图片添加水印 vue实现上传图片添加水印

    想了解vue实现上传图片添加水印的相关内容吗,牛先森家的牛奶在本文为您仔细讲解vue上传图片添加水印的相关知识和一些Code实例,欢迎阅读和指正,我们先划重点:vue上传图片添加水印,vue图片添加水印,vue图片水印,下面大家一起来学习吧。..

网友评论

Copyright 2020 www.ben10gamesx.com 【Win11软件站】 版权所有 软件发布

声明:所有软件和文章来自软件开发商或者作者 如有异议 请与本站联系 点此查看联系方式