有些东西一直困扰着我,我需要一个anwer,
char *p = "hello world";
p="wazzup";
p="Hey";
这里我声明一个指向字符串的指针(换句话说,我是通过使用指针创建一个字符串)
我有一些奇怪的结果,如果我使用char数组字符串,我通常不会得到
cout <<p<< endl; //"Hey" Gets printer
cout <<p+8<< endl; // I kept adding numbers till "wazzup" got printed
cout <<p+29<< endl; // No matter how much I increment, I cant print "Hello World"
所以我的问题是:
当我更改char指针指向的值时。是吗
覆盖原始数据,就像使用char数组一样;
或者它在内存中创建一个新字符串并指向它;
或是否在旧字符串的开头添加新字符串(包括null);
或者它是否在内存中的新位置创建了一个新字符串,我只能偶然打印“wazzup”
答案 0 :(得分:4)
它没有上述任何选项。更改指针的值只会更改为它指向的内存中的地址。在p
的赋值的每种情况下,它被设置为指向(不同的)字符串文字的第一个字符 - 它存储在内存中。
使用指向超出字符串文字结尾的指针的行为,例如
cout <<p+8<< endl
未定义。这就是使用指针充满危险的原因。
您看到的行为取决于实现:编译器将字符串文字存储在内存中,因此在一个文件的末尾运行会运行到另一个文件中。使用不同的编译器编译时,您的程序可能同样崩溃。
答案 1 :(得分:2)
通过添加到指针,您将增加地址值...因此,在打印时,它将打印存储在该内存位置的值,而不是其他内容......
如果可以打印
"hello world"
"wazzup"
这将是侥幸:)
答案 2 :(得分:1)
所有这三个都是字符串文字常量。它们直接出现在您的可执行文件的二进制文件中,每次分配p
时,您都会在内存中指向这些位置。它们是完全独立的记忆;将p
重新分配给另一个不会修改任何字符串数据。
答案 3 :(得分:1)
每次分配指针时,您只会将指针指向其他内容。因此,任何地方都无法覆盖数据。引擎盖下发生的事情取决于实现,所以你看到的只是纯粹的机会。当你这样做时:
cout <<p+8<< endl;
你超越了字符串文字的范围,调用了未定义的行为。
答案 4 :(得分:1)
当我更改char指针指向的值时。是吗
- 像对待char数组一样覆盖原始数据。 不,地址空间的数据部分包含所有三个字符串“Hello World”,“wazzup”和“Hey”。更改指针时,只需将p中的值更改为上述任一字符串的起始地址即可。更改指针指向的地址并更改指针指向的值是两回事。
- 或者它在内存中创建一个新的字符串并指向它。 编译器在编译时创建字符串(字符字节),在运行时创建 NOT 。
- 或者它在内存中的新位置创建一个新字符串,我只能偶然打印“wazzup” 我认为上面的答案涵盖了这个问题。
- 或者它是否在旧字符串的开头添加新字符串。(包括null) 这取决于编译器规范。
答案 5 :(得分:1)
三个字符串不在同一个内存位置。这三个内存可能是顺序或不同的位置。如果编译器分配三个内存,那么你可以使用+/-某个值找到它。这完全取决于编译器。在c中你可以准备任何内存位置,这样你就不会在+/-然后指针p时出现任何错误。
答案 6 :(得分:0)
由于它们不是相同的字符串,因此它们位于内存的不同部分。我认为它们可以通过64字节对齐分开。试试p + 64:)
只有相同的字符串位于内存的相同位置,并且只有在编译器支持时才会使用。
p + 64有“wazzup”概率,p + 128有“嘿”(如果使用VC ++ 2010 express,你有pentium-m cpu,你使用windows xp sp-3)
cout <<*(p+64)<< endl;
cout <<*(p+128)<< endl;