【问题标题】:const char* 's in C++const char* 在 C++ 中
【发布时间】:2010-01-04 18:32:04
【问题描述】:

C++ 中的字符串表达式是如何工作的?

考虑:

#include <iostream>
using namespace std;

int main(int argc, char *argv[]){

    const char *tmp="hey";
    delete [] tmp;

    return 0;
}

“嘿”表达式存储在哪里以及如何存储,为什么在我尝试删除它时会出现分段错误?

【问题讨论】:

  • 此代码是一个错误。您不能删除文字。
  • 我认为提问者很了解,Pavel。问题问为什么

标签: c++ string


【解决方案1】:

在这种(有些特殊的)情况下,它的存储位置由编译器决定。但是,这对您来说并不重要——如果您不使用new 分配内存,那么尝试使用delete 释放它并不是很好。你不能delete以你分配的方式分配内存。

如果你想控制该资源的释放,你应该使用std::string,或者使用malloc()分配一个缓冲区。

【讨论】:

  • 哦...所以我认为不太建议在 const char 数据上使用指针
  • @Pyjong:你可以随意使用指针来引用 const char 数据,只是不要试图删除指针所引用的内存。
  • @Nick,我还要补充一点,如果您使用malloc 分配,您还应该确保使用free 释放。
  • @Nick Meyer:好点。这似乎超出了当前讨论的范围...... :-)
【解决方案2】:

当您将const char * 指针分配给示例中的"hey" 等常量字符串时,hey\0 序列作为静态变量存储在二进制文件本身中。它不能被删除,也不应该被操纵。根据架构/操作系统,它在操作时可能会出现段错误

如果您要执行const char[] tmp = "hey",则数据将存储在堆栈中,并且可以被操作(但不能删除,因为一旦堆栈清除,它将被释放:当函数返回时)。

不要delete[] 任何不是new[] 的东西。

【讨论】:

    【解决方案3】:

    "hey" 是一个字符串字面量,存储在可执行文件的数据段中,在加载时映射到进程的内存中。文字所在的特定部分被映射只读。这是使用 g++ -S 的代码生成的程序集的 sn-p:

    
    ...
        .section    .rodata
    .LC0:
        .string "hey"
        .text
        .align 2
    ...
    

    所以数据确实是只读的,并且尝试使用delete 对其进行操作会导致段错误。

    【讨论】:

      【解决方案4】:

      const char *tmp="hey";

      “嘿”存储在read-only area of the Data Segment 中。 当应用程序启动时,“嘿”将被映射到只读内存页面。

      const char *tmp="hey";
      delete [] tmp;
      

      deleteaccess and change some allocation metadata., 但在只读内存页面中“嘿”。

      不允许在 READ-ONLY 中更改值,so segmentation fault happened

      【讨论】:

        【解决方案5】:

        您不能删除静态资源:它们是只读的。

        【讨论】:

          【解决方案6】:

          这是怎么回事。

          "hey" 的意思是将字符串'hey' 放入二进制图像的某处并给我它的地址,这是表达式的值(“hey”)。它的类型为 char*。在这个地址,你有 4 个字节。 'h'、'e'、'y' 和 0(0 称为传统的空终止符。(与电影终止符无关)这就是字符串文字在 C 中的工作方式。

          你可以这样传递这个文字:“一个字符串的地址”。

          你不能删除它。

          当你构造 std::string("hey") 时,它会获取这个指向的字符串,并将其复制到其他地方 - 到新分配的内存中。

          【讨论】:

            【解决方案7】:

            您不能删除常量数据。如果您之前调用过new char[stringSize],您只会调用delete[] tmp

            【讨论】:

              【解决方案8】:

              你没有在字符串上调用new。无论如何,这是一个潜在的内存泄漏,对于每个new,都有一个delete,同样对于mallocfree。您删除了对指针的内存引用,从这个词的意义上讲,该指针简单地是一个静态字符数组。

              希望这会有所帮助, 最好的祝福, 汤姆。

              【讨论】:

                【解决方案9】:

                字符串"hey"作为程序的一部分预先分配了空间,所以它只在程序启动时出现,在程序结束时消失。

                如果你想看一个程序分配内存,使用它,然后删除它,那么看看这个:

                #include <iostream>
                using namespace std;
                
                int main(int argc, char *argv[]){
                
                    const char *hey="hey";
                    char* tmp=new char[4]; // NB allocate 4 chars for "hey" plus a null terminator
                    strcpy(tmp,hey);  // copies the string and null terminator
                    cout << tmp << endl;
                    delete [] tmp;
                    // must not use tmp now as it points to deallocated memory
                    // must not delete hey
                
                    return 0;
                }
                

                注意我是如何碰巧使用tmp 删除了new'd 内存的。我本来可以这样做的:

                    cout << tmp << endl;
                    hey = tmp;
                    delete [] hey;
                

                最终我们用heytmp指向new的内存都没有关系,只要我们正确删除它以避免内存泄漏即可。

                【讨论】:

                  猜你喜欢
                  • 2020-08-01
                  • 2022-08-11
                  • 1970-01-01
                  • 2020-01-09
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多