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的位置,因而你操作的是数据段中的那个字符串,就是上面的原因,系统会阻止你修改数据段,因而报错
到此这篇关于C++中char[]能修改char*却不行的文章就介绍到这了,更多相关C++ char*不能修改内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!