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代码
本文地址:http://www.codeinn.net/misctech/184444.html