我正在使用一些随机值初始化char
指针,当我尝试删除它时,我无法做到。那是为什么?
这是我正在做的事情:
int main()
{
char *s = new char[50]; // I know there is no reason for using new if initializing, but in order to use delete we need to allocate using new.
s = "Harry";
delete s;
return 0;
}
答案 0 :(得分:16)
如果你真的想用指针练习,你需要修复你的代码。主要问题是你试图将字符串文字(这里是 const char [6] )分配给指针s
然后尝试通过调用delete来调用它来调用未定义的行为({ {1}})。
UB
只需使用char *s = new char[50];
strcpy(s, "Harry"); // don't assign string literal to it
// re-assign pointer to string literal,
// lost pre-allocated memory position and caused delete to fail
// it's UB to modify string literal
delete []s; // new[]/delete[], new/delete need to be called in pair.
。
std::string
答案 1 :(得分:10)
问题在于此作业后:
s = "Harry";
然后您的s
不再指向您已分配的内存。它指向不同的数组,或者const char[6]
来确切。另一个数组未动态分配,并且不在堆上。你不能delete
不在堆上的变量。
此外,通过在释放动态分配的内存之前将s
指针更改为指向其他位置,会引入内存泄漏。
要修复代码,请使用"Harry"
将s
复制到strcpy
数组中,或使用std::string
代替。
答案 2 :(得分:4)
你应该永远不会用这种方式用字符串常量初始化指针。它会造成内存泄漏,这可能非常危险。
当您使用new分配内存时,在堆中分配了50个char内存,并在s中返回其指针。当您尝试使用s="Harry
“初始化此值(错误方式)时,会在堆栈中分配一个新空间,使用此值初始化并在s中返回。
使用delete
调用无法删除在堆栈中分配的内存,因为它仅适用于堆。
此外,最初使用new分配的内存不能再使用s访问。因此,这里有内存泄漏。
在错误的初始化后,您可以通过对程序进行少量更改来注意指针s
中的不同地址:
#include <stdio.h>
int main()
{
char *s = new char[50];
printf("\n %u",s); // print address before init
s = "Harry";
printf("\n %u",s); // print address after init
// delete s; // cannot delete from stack
return 0;
}
与其他人已经建议的一样,应使用
初始化一个字符数组strcpy(s, "Harry");
答案 3 :(得分:3)
char *实际上不是字符串。它是一个指向某个字符的指针,其中包含更多字符并以'\ 0'结尾。
C中的字符文字(因此在C ++中)像“abc”只是一个字符数组,编译器默默地添加'\ 0'。将数组分配给指针时,该数组会以静默方式将指针转换为第一个元素。 s =“Harry”表示,指针s被赋予字符串文字“Harry”中第一个字符的地址。因此旧值丢失,因为这是动态分配的字符数组的地址,所以应该发生泄漏。
另一方面,std :: strcpy将字符串中的字符串从一个数组复制到另一个数组。不会更改任何指针,只会复制内存块。指向目标数组的指针后来仍指向目标数组,只有该数组中的数据发生了变化。
答案 4 :(得分:-1)
我认为初始化指针不会发生这种情况。
当使用指针时,你只能删除(释放)它所指向的内存,而不是指针本身,因为它是一个自动对象,并将在块的末尾被删除。