【问题标题】:Program crashes when trying to set a character of a char array尝试设置 char 数组的字符时程序崩溃
【发布时间】:2011-02-15 17:49:13
【问题描述】:

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

代码:

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* 汗水 = cc;

这真的让我很烦,我不明白,为什么版本 1 不起作用。 希望你们能帮帮我,否则我会疯了。

【问题讨论】:

  • 第一个版本有什么问题?你为什么使用 char 数组而不是 std::string?

标签: c++ char


【解决方案1】:

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

【讨论】:

    【解决方案2】:
    char* sweat ="Sweater";
    sweat[0] = '\0'
    

    这里sweat 指向一个CONSTANT 数据。 “毛衣”是常量文字数据,位于只读内存中的某处,sweat 指向该数据。 它不会复制它。因此,当您执行sweat[0]='\0' 时,它会尝试更改 CONSTANT 数据的第一个字符。因此错误。顺便说一句,如果你在声明中没有写const,一个好的编译器应该给出警告,如const char* sweater = "Sweater"。在此处查看警告:http://www.ideone.com/P47vv

    但是当你写char sweat[] = "Sweater"时,会创建一个char数组,从"Sweater"的CONSTANT数据中复制数据;该数组的元素本身是可修改的!


    让我们看一个有趣的事情:因为在第一种情况下,它不会复制 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

    【讨论】:

      【解决方案3】:

      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++ 的静态类型系统中是一件令人讨厌的事情。诅咒你,向后兼容!

      【讨论】:

        【解决方案4】:

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

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

        这仅适用于 char sweat[] = "XXXX"; 或 char sweat[20];

        【讨论】:

          【解决方案5】:

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

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

          或者更好:

          std::string sweater = "";
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2015-11-20
            • 1970-01-01
            • 1970-01-01
            • 2015-08-22
            • 1970-01-01
            • 2020-07-25
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多