1

我正在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;
}
4

5 回答 5

16

如果你真的想练习指针,你需要修复你的代码。主要问题是您试图将字符串文字(此处为const char[6])分配给指针,然后尝试通过调用调用未定义行为( )s的 delete 来修改它。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了。

#include <string>
std::string s("Harry"); // no worries
于 2013-07-29T12:20:42.083 回答
10

问题是在这个分配之后:

s = "Harry";

然后你s不再指向你分配的内存。它指向一个不同的数组,或者const char[6]准确地说是一个。另一个数组不是动态分配的,也不在堆上。您不能使用不在delete堆上的变量。

此外,通过s在释放动态分配的内存之前将指针更改为指向其他内容,您会引入内存泄漏。

要修复您的代码,请使用 复制"Harry"s数组中strcpy,或者std::string改为使用。

于 2013-07-29T12:29:10.647 回答
4

您永远不应该以这种方式使用字符串常量初始化指针。它会造成非常危险的内存泄漏。当您使用 new 分配内存时,在堆中分配了 50 个字符的内存,其指针在 s 中返回。当您尝试使用s="Harry" 初始化此值(错误的方式)时,会在堆栈中分配一个新空间,使用此值初始化并在 s 中返回。

堆栈中分配的内存不能使用deletecall 删除,因为它仅适用于堆。此外,最初使用 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");
于 2013-07-29T12:41:15.307 回答
3

char* 实际上不是字符串。它是指向某个字符的指针,该字符后面有更多字符,并以'\0'结尾。

C 中的字符文字(因此在 C++ 中)像“abc”只是一个字符数组,编译器会默默地添加一个 '\0'。当您将数组分配给指针时,数组会静默地将指针转换为第一个元素。s = "Harry" 的意思是,指针 s 被分配了字符串文字 "Harry" 中第一个字符的地址。所以旧值丢失了,因为这是动态分配的字符数组的地址,所以应该会发生泄漏。

另一方面,std::strcpy 将一个字符串逐个字符地从一个数组复制到另一个数组。不会更改指针,只会复制内存片段。之后指向目标数组的指针仍然指向目标数组,只是该数组中的数据发生了变化。

于 2013-07-29T12:30:29.687 回答
-1

我认为初始化指针不会发生这种情况。

使用指针时,您只能删除(释放)它指向的内存,而不是指针本身,因为它是一个自动对象,将在块的末尾被删除。

于 2013-07-29T12:25:19.503 回答