简体   繁体   English

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

[英]Program crashes when trying to set a character of a char array

I got this weird behavior of my programm, that i cant figure out. 我的程序出现这种奇怪的行为,我无法弄清楚。 My professor showed me a flaw in my programm, where i just copy a char pointer when i construct an object instead of making a new copy of the whole array, so you can fool around with it. 我的教授向我展示了我程序中的一个缺陷,在构造一个对象时,我只是复制一个char指针,而不是对整个数组进行新的复制,因此您可以无所事事。 He demonstrated this with similar code like this. 他用类似的代码演示了这一点。

For the code: 对于代码:

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

now if i instead make it: 现在,如果我改为:

char* sweat ="Sweater";

the program runs fine till i try sweat[0] = '\\0'; 程序运行正常,直到我尝试出汗[0] ='\\ 0'; It simply crahes then. 然后它就崩溃了。

However this works: char cc[] ="Sweater"; 但这有效:char cc [] =“ Sweater”; char* sweat = cc; char *汗水= cc;

It is really bugging me, that i dont understand, why version 1 does not work. 我不明白,为什么版本1无效,这真是困扰我。 Hope you guys can help me out, or else i will go crazy wondering about this. 希望你们能帮助我,否则我会为此而疯狂。

"Sweater" is a string literal, which may reside in read-only memory. “毛衣”是字符串文字,可以驻留在只读存储器中。 Using the char[] syntax copies this literal into a char array, using the char * syntax (which really should be const char *) just points at the original string literal. 使用char []语法将此文字复制到char数组中,使用char *语法(实际上应该是const char *)仅指向原始字符串文字。

char* sweat ="Sweater";
sweat[0] = '\0'

Here sweat points to a CONSTANT data. 这里sweat指向恒定数据。 "Sweater" is const literal data, residing somewhere in read-only memory, and sweat points to this data as such. “毛衣”是常量文字数据,位于只读存储器中的某个位置,并且sweat本身就指向此数据。 It doesn't make a copy of it. 它不会复制它。 So when you do sweat[0]='\\0' , it tries to change first character of the CONSTANT data. 因此,当您sweat[0]='\\0' ,它将尝试更改CONSTANT数据的第一个字符。 Hence the error. 因此,错误。 By the way, a good compiler should give warning if you don't write const in your declaration, as const char* sweater = "Sweater" . 顺便说一句,如果您未在声明中编写const ,那么好的编译器应发出警告,因为const char* sweater = "Sweater" See the warning here : http://www.ideone.com/P47vv 请在此处查看警告: http : //www.ideone.com/P47vv

But when you write char sweat[] = "Sweater" , an array of char is created, copying the data from the CONSTANT data which is "Sweater" ; 但是,当您编写char sweat[] = "Sweater" ,将创建一个char数组,并从CONSTANT数据(即"Sweater"复制数据; that array's element itself is modifiable! 该数组的元素本身是可修改的!


Lets see an interesting thing: since in the first case, it doesn't make a copy of the const data, so no matter how many variables you declare (all pointing to the same data), the address would be same for all variables. 让我们看一个有趣的事情:由于在第一种情况下,它不会复制const数据,因此,无论您声明多少变量(全部指向同一数据),所有变量的地址都将相同。 See this: 看到这个:

#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;
}

Output: 输出:

0x8048610
0x8048610

Means, both printfs print the same address! 意思是,两个printfs都打印相同的地址!

See yourself here : http://www.ideone.com/VcyM6 在这里见自己: http : //www.ideone.com/VcyM6

ASCII art to the rescue! 救援ASCII艺术! The char sweat[] version looks like this in memory: 内存中的char sweat[]版本看起来像这样:

       +---+---+---+---+---+---+---+---+
sweat: |'S'|'w'|'e'|'a'|'t'|'e'|'r'| 0 |   char[8]
       +---+---+---+---+---+---+---+---+

Whereas the char* sweat version looks like this: char* sweat版本看起来像这样:

       +---+---+---+---+---+---+---+---+
       |'S'|'w'|'e'|'a'|'t'|'e'|'r'| 0 |   const char[8]
       +---+---+---+---+---+---+---+---+
         ^
         |
         |
       +-|-+
sweat: | | |   char*
       +---+

That's right, a char* pointing to a const char . 是的, char*指向const char The fact that you can assign a string literal to a non-const character pointer is a nasty holy in C++'s static type system. 可以将字符串文字分配给非const字符指针的事实在C ++的静态类型系统中是很讨厌的。 Curse you, backward compatibility! 诅咒你,向后兼容!

In the version that doesn't work, you are not creating any array of chars. 在不起作用的版本中,您没有创建任何字符数组。 You are only playing with pointers. 您只在玩指针。

For sweat[0] = '\\0' to be a valid statement, you need sweat to be an actual array of chars. 为了使sweat[0] = '\\0'为有效的语句,您需要sweat成为实际的字符数组。

This is done only with char sweat[] = "XXXX"; 仅使用char sweat[] = "XXXX"; or char sweat[20]; 或炭sweat[20];

C++ is not a managed language. C ++不是托管语言。 Avoid creating pointers to character arrays that don't have a proper size. 避免创建指向不正确大小的字符数组的指针。 Both of the following examples are better solutions: 以下两个示例都是更好的解决方案:

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

Or better yet: 或者更好:

std::string sweater = "";

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM