尝试设置字符数组的字符时程序崩溃

问题描述 投票:0回答:5

我的程序出现了这种奇怪的行为,我无法弄清楚。我的教授向我展示了我的程序中的一个缺陷,当我构造一个对象时,我只是复制一个 char 指针,而不是创建整个数组的新副本,这样你就可以随意使用它。他用类似的代码演示了这一点。

代码:

char sweat[] ="Sweater";
warenkorb = new WareImKorb(new Textil (205366,4.2,sweat,40),2,warenkorb);
sweat[0] = '\0';

现在如果我成功了:

char* sweat ="Sweater";

程序运行良好,直到我尝试汗 [0] = ' '; 然后它就崩溃了。

但是这有效: char cc[] ="毛衣"; 炭*汗水=抄送;

这真的让我很烦恼,我不明白为什么版本 1 不起作用。 希望你们能帮助我,否则我会疯狂地思考这个问题。

c++ char
5个回答
5
投票

“Sweater”是一个字符串文字,可能驻留在只读存储器中。使用 char[] 语法将此文字复制到 char 数组中,使用 char * 语法(实际上应该是 const char *)仅指向原始字符串文字。


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
投票

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
。事实上,您可以将字符串文字分配给非常量字符指针,这在 C++ 的静态类型系统中是一个令人讨厌的神圣现象。诅咒你,向后兼容!


0
投票

C++ 不是托管语言。避免创建指向大小不正确的字符数组的指针。以下两个示例都是更好的解决方案:

char* sweater = new char[10];
sweater[0] = '\0';
delete [] sweater;
sweater = NULL;

或者更好:

std::string sweater = "";

0
投票

在不起作用的版本中,您没有创建任何字符数组。你只是在玩指针。

要使

sweat[0] = '\0'
成为有效的语句,您需要
sweat
成为实际的字符数组。

这只能通过

char sweat[] = "XXXX";
char sweat[20];

完成
© www.soinside.com 2019 - 2024. All rights reserved.