在Linux Qt Creator c++中使用malloc for char *时接收SIGSEGV信号

Receive SIGSEGV signal when using malloc for char * in Linux Qt Creator C++

本文关键字:char 信号 SIGSEGV for malloc Creator Qt Linux c++      更新时间:2023-10-16

当我在QT Linux c++上使用malloc()运行以下代码为char *分配内存时,SIGSEGV在大约250次执行后发出信号。

for(int i = 0; i < 10000; i++)
{
   char * test = (char * )malloc(500);
   test = "mas";
   cout<<test<<endl; 
}

我尝试使用free()或delete(),但它们也会触发系统信号。

有什么问题吗?

主要问题是您踩到了malloc()'ed指针。多次踩上去:

// Original test case
for(int i = 0; i < 10000; i++) {
   char * test = (char * )malloc(500);
   test = "mas";  // BAD!!! 
                  // You've just stepped on your "malloc'ed" pointer with a *different pointer!!!!
   cout<<test<<endl; 
}

这里有一个选择。请注意,您还必须有一些方法来"记住"每个malloc()的指针,以便您可以在适当的时候"释放"它:

// Better:
for(int i = 0; i < 10000; i++) {
   char * test = (char * )malloc(500);
   if (test == NULL) {
     cout <<  "malloc error!" << endl;
     break;
   }
   strcpy (test, "mas");
   cout<<test<<endl; 
   free (test);
}

您已经更改了指针测试的值。您需要使用memcpy或类似的方法将值"mas"复制到缓冲区中。

使用std::string

更好

代码:

test = "mas";

并不像你想象的那样。您认为它将字符串"mas"复制到test所指向的缓冲区中。实际上所做的是改变test指向的内容。现在它不再指向使用malloc分配的内存,而是指向静态分配的字符缓冲区。

当你用malloc或new分配内存时,你只能得到一个指针,所以你必须用不同的方法来处理——使用strcpy、strcmp等函数(如果你需要检查文本的相等性,你也不能只比较指针)。在任何c++书籍中阅读更多关于指针的内容。创建文本而不显式分配内存是可能的,例如,这是合法的:

const char *text = "my text";

但是像你在问题中展示的进一步修改不是(注意这里的const,它给了我们更多的安全性)。在这种情况下,文本是由编译器本身在内存中的某个地方创建的(我现在正在简化事情),只有指针被分配。在这种情况下,您不能修改该文本(至少不安全)。

下一件事,当你分配任何内存时,你必须手动释放它,至少在像C/c++这样的语言中,内存管理(垃圾收集器等)并不真正存在。如果您跳过这一步,您将比您想象的更快地遇到麻烦(例如,内存不足异常)。

这个语句:

    test = "mas";

不复制字符串,而是复制指针。

要在C中复制字符串,请小心使用 strcpy(3) (通常strncpy更好)

    strcpy(test, "mas");

但是你真的应该使用std::string(正如Vinbot回答的那样),因为你是用c++

编写代码的。

另外,在Linux上用g++ -g Wall编译c++代码(和用gcc -g -Wall编译C代码)来获得警告和调试信息。学习如何使用gdb调试器和valgrind

请参见对相关问题的回答