如何删除我在以下代码中指定的指针:
char* ptr;
ptr=new char(65); // memory for one char is created and is assigned 'A'
strcpy(ptr,"asdf"); // how can string of length 4 chars are copied
delete ptr; // why am I getting debug error of Heap corruption detected
我正在使用Visual C ++ 2005
答案 0 :(得分:7)
您正在分配一个char而不是一个数组。使用:
char* ptr;
ptr=new char[65];
strcpy(ptr,"asdf");
delete[] ptr;
就像现在一样,你将第一个a
写入已分配的char,其余的则写入从未分配给你的任意内存。运行时检测到(在调试版本中)并抱怨。
对我的答案中的问题部分发表评论:
C ++没有任何机制来识别问题代码中的潜在错误。编译器知道传递给strcpy
的缓冲区大小的唯一方法是使用静态分析,这可能有效,也可能无效。但即使这样,编译器也不知道strcpy
的语义。因此,在编译时,它无法警告您错误。
现在,当缓冲区在运行时传递给strcpy
时,strcpy
无法判断缓冲区有多大。所以它只是假设调用者提供了一个合适的缓冲区,并继续复制。如果幸运的话,溢出分配的缓冲区将导致由于写入未分配的页面而立即崩溃。如果没有,你会得到内存损坏。
您获得的错误是调试版本中使用的机制的结果:内存管理器分配的字节数比您要求的多一些,并在其上写入特殊模式。然后,当释放分配的内存时,它会检查该模式是否仍然存在。如果没有,它会抱怨用户的代码已写入其中。在发布版本中,您没有那些额外的检查,并且此类错误可能会导致损坏而不会被发现。
避免此类情况的唯一方法是编写更安全的代码:
答案 1 :(得分:4)
因为你通过尝试将4个字符“asdf”(实际上是5,如果count null终结符)填充到一个只能通过这样做的1个字符的内存块中来破坏堆:
strcpy(ptr,"asdf");
更新
您应该根据需要(或更多)分配尽可能多的内存。如果你需要将4个字符的字符串复制到一个内存块中,你应该确保内存块足够大以保留它,因此,在你的情况下,你应该使用
ptr=new char[5];
分配5 char
s(每个字符串应该有4个字符串+ 1个空终结符),并释放分配的内存,你应该使用
delete[] ptr;
[]
表示您要删除一个字符数组,而不只是一个字符。
答案 2 :(得分:1)
这实际上是错的。你想要:
ptr=new char[65]; // memory for one char is created and is assigned 'A'
strcpy(ptr,"asdf"); // how can string of length 4 chars are copied
delete[] ptr;
更好:
char ptr[65];
strcpy(ptr,"asdf");
最好的:
std::string str("asdf");
答案 3 :(得分:1)
这是内存损坏的典型案例。堆是具体的。 ptr
只分配了1个字节,并且您正在执行溢出1个字节的字符串复制操作。
您的程序可能不一定立即崩溃,但会导致随机崩溃或未定义的行为。
答案 4 :(得分:1)
首先,您为ptr
分配了一个字节。并为其指定了“A”。
然后尝试使用ptr
将大小为5的字符串复制到strcpy
。
你可能想知道为什么它没有在strcpy
电话本身崩溃。原因是strcpy
未对分配大小执行任何验证,因此导致缓冲区溢出导致未定义行为。
参考:Segmentation fault in strcpy
char* ptr;
ptr=new char[5]; // I see no point in assigning 'A' as you replace it in next statement.
strcpy(ptr,"asdf");
delete[] ptr; // delete[] is used as memory is allocated for arrays of elements.
此外,在Visual Studio 2005中,您可以使用strcpy
,strcpy_s
的安全替代方案。