C++无效指针错误

C++ invalid pointer error

本文关键字:错误 指针 无效 C++      更新时间:2023-10-16

我从下面的代码中得到了无效点错误,我不明白为什么。我所要做的就是从一个向量中删除堆上的一些空闲字符串:

void func() {
    vector<string>* vec = new vector<string>;
    vec->push_back(*(new string("1")));
    vec->push_back(*(new string("2")));
    for(vector<string>::iterator itr = vec->begin(); itr != vec->end(); ++itr)
    {
        string* ptr = &(*itr);
        delete(ptr);
    }
}

EDIT:是因为push_back创建了字符串的副本吗?

您的错误是因为元素不是动态分配的;矢量是。你要做的需要:

void func() 
{
    vector<string*> vec;
    vec.push_back(new string("1"));
    vec.push_back(new string("2"));
    for(vector<string*>::iterator itr = vec.begin(); itr != vec.end(); ++itr)
    {
        string* ptr = *itr;
        delete(ptr);
    }
}

但老实说,我看不出有什么理由这么做。编写时,您的代码不仅试图删除从未实际分配的内存,还会泄露所分配的内存。

的理由将指向对象的指针存储在这样的向量中(例如对象实际上来自其他地方的另一个容器,您需要一个临时列表来进行自定义排序操作,而不会干扰原始内容),但有一件事告诉我,您不需要这样做。

首先,行

vec->push_back(*(new string("1")));

导致内存泄漏。从new string("1")返回的值是指向新分配的字符串对象的指针。但是,当您取消引用它并将其插入到向量中时,会创建并插入堆分配对象的副本。但是,您最初在堆上分配的实际字符串对象被泄露了。

从本质上讲,向量是按值存储字符串对象,而不是指向字符串对象的指针。插入到向量中的字符串对象的副本不是堆分配的对象(不是用new分配的对象)。当然,你不能用new分配delete。因此,当您调用delete(ptr)时,会导致未定义的行为。

你似乎想要的是:

vector<string*>* vec = new vector<string*>;

然而,总的来说,我看不出有什么令人信服的理由可以解释为什么要在堆上分配所有内容。在C++中,只要可行,最好使用堆栈分配和具有值语义的容器,除非您有某种理由需要堆分配(例如多态对象的容器,在这种情况下,无论如何都应该使用智能指针)。通常,当新的C++程序员到处使用堆分配的对象和new关键字时,这表明他们对从Java或C#等托管语言导入的编程风格的音译很差。

不,您不是-您的向量存储string对象,而不是指向string对象的指针。这就是为什么在push_back调用中有*——您正在取消引用返回的指针。

您正在添加使用new创建的动态字符串的副本,而该动态字符串将丢失,因为您从未存储new返回的指针。