我得到了我的程序这种奇怪的行为,我无法弄清楚。我的教授在我的程序中向我展示了一个缺陷,我只是在构造一个对象而不是制作整个数组的新副本时复制一个字符指针,所以你可以随意使用它。他用类似的代码证明了这一点。
代码:
char sweat[] ="Sweater";
warenkorb = new WareImKorb(new Textil (205366,4.2,sweat,40),2,warenkorb);
sweat[0] = '\0';
现在,如果我改为:
char* sweat ="Sweater";
程序运行良好,直到我尝试汗[0] ='\ 0'; 那就简直就是了。
然而这有效: char cc [] =“毛衣”; char * sweat = cc;
这真让我烦恼,我不明白,为什么版本1不起作用。 希望你们能帮助我,否则我会为此感到疯狂。
答案 0 :(得分:5)
“Sweater”是一个字符串文字,可以驻留在只读内存中。使用char []语法将这个文字复制到一个char数组中,使用char *语法(实际上应该是const char *)只指向原始字符串文字。
答案 1 :(得分:3)
char* sweat ="Sweater";
sweat[0] = '\0'
此处sweat
指向CONSTANT数据。 “Sweater”是const文字数据,驻留在只读内存中的某个位置,sweat
指向此数据。 它不会复制它。因此,当您执行sweat[0]='\0'
时,它会尝试更改CONSTANT数据的第一个字符。因此错误。顺便说一句,如果你没有在声明中写const
,那么好的编译器应该发出警告,如const char* sweater = "Sweater"
。请在此处查看警告:http://www.ideone.com/P47vv
但是当您编写char sweat[] = "Sweater"
时,会创建一个char数组,从CONSTANT数据中复制数据"Sweater"
;该数组的元素本身是可修改的!
让我们看一个有趣的事情:因为在第一种情况下,它不会复制const数据,所以无论你声明了多少变量(都指向相同的数据),地址都是相同的所有变量。见:
#include<cstdio>
int main() {
char* sweat ="Sweater"; //notice the warning
const char* another ="Sweater"; //no warning!
std::printf("%p\n", sweat); //print the address
std::printf("%p\n", another); //print the address
return 0;
}
输出:
0x8048610
0x8048610
表示两个printfs都打印相同的地址!
在这里看到自己:http://www.ideone.com/VcyM6
答案 2 :(得分:2)
ASCII艺术救援! char sweat[]
版本在内存中看起来像这样:
+---+---+---+---+---+---+---+---+
sweat: |'S'|'w'|'e'|'a'|'t'|'e'|'r'| 0 | char[8]
+---+---+---+---+---+---+---+---+
char* sweat
版本看起来像这样:
+---+---+---+---+---+---+---+---+
|'S'|'w'|'e'|'a'|'t'|'e'|'r'| 0 | const char[8]
+---+---+---+---+---+---+---+---+
^
|
|
+-|-+
sweat: | | | char*
+---+
这是正确的,char*
指向const char
。您可以将字符串文字分配给非const字符指针,这在C ++的静态类型系统中是一个令人讨厌的神圣事物。诅咒你,向后兼容!
答案 3 :(得分:0)
在不起作用的版本中,您不会创建任何字符数组。你只是玩指针。
要使sweat[0] = '\0'
成为有效语句,您需要sweat
作为实际的字符数组。
仅在使用char sweat[] = "XXXX";
或char sweat[20];
答案 4 :(得分:0)
C ++不是托管语言。避免创建指向不具有适当大小的字符数组的指针。以下两个示例都是更好的解决方案:
char* sweater = new char[10];
sweater[0] = '\0';
delete [] sweater;
sweater = NULL;
或者更好:
std::string sweater = "";