【问题标题】:Char pointer dereference字符指针取消引用
【发布时间】:2016-01-11 02:34:11
【问题描述】:

我尝试将char *代表的句子中的大写改为小写。 我得到一个错误:当我取消引用指针时访问冲突。

// Uppercase to lowercase
char *str = "My sentence";
*str = 'm';

【问题讨论】:

  • 为什么不标记一种语言?

标签: c dereference


【解决方案1】:

原因是你使用了错误的格式来定义一个字符串。你想要:

 char str[] = "My Sentence";
 *str = 'm';

您所写的内容定义了一个指针,然后将“我的句子”分配给 指针 作为内存地址。您收到访问冲突,因为您不拥有“My Sente”的内存,这很可能是被引用的地址。

【讨论】:

    【解决方案2】:

    代码"My sentence" 是一个“字符串文字”,系统有意将字符串文字放置在标记为只读的内存中,以帮助捕获错误。在 C 中,更改字符串文字中的字节是未定义的行为(即使字符没有 const 限定符!),而在 C++ 中,字符是 const 并且您可能无法编辑常量内存。这些规则的好处是,如果您在一个程序中有两次相同的字符串,则可以对它们进行重复数据删除,并且只保留一份副本。

    您可能希望分配一些新内存并在那里编辑您的字符串。 @David Hoelzer 的回答显示了如何将副本放在堆栈内存上。以下是如何在堆上做到这一点:

    char *str = calloc(200, 1);
    strcpy(str, "My sentence");
    *str = 'm';
    /* ... */
    free(str);
    

    【讨论】:

      【解决方案3】:

      是undefined behavior6.4.5p6 String literals, page 63对这样的字符串文字进行变异:

      .... 如果程序试图修改这样的数组,行为是 未定义。

      您可以使用字符串文字来初始化数组,而不是改变字符串文字的地址(地址由ptr 指向)。

      在 ISO9899 的第 130 页上,您会看到:

      声明

       char s[] = "abc", t[3] = "abc";
      

      定义“普通”字符数组对象 s 和 t,其元素用字符串字面量初始化。 该声明与

      相同
      char s[] = { 'a', 'b', 'c', '\0' },
      t[] = { 'a', 'b', 'c' };
      

      数组的内容是可以修改的。另一方面,声明

      char *p = "abc";
      

      定义 p 类型为“pointer to char”,并将其初始化为指向类型为“array of char”的对象 长度为 4,其元素用字符串字面量初始化。 如果尝试使用 p 来 修改数组的内容,行为未定义。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-07-04
        • 1970-01-01
        • 2013-02-20
        • 2019-05-20
        • 1970-01-01
        相关资源
        最近更新 更多