在Linux Qt Creator c++中使用malloc for char *时接收SIGSEGV信号
Receive SIGSEGV signal when using malloc for char * in Linux Qt Creator C++
当我在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
请参见对相关问题的回答