C++ C++;错误:双重自由或损坏(fasttop)

C++ C++;错误:双重自由或损坏(fasttop),c++,vector,C++,Vector,我想知道为什么下面的程序在运行程序时会出现错误“double free or corruption(fasttop)”。我知道我可以用字符串代替字符数组。但是我想使用具有动态内存分配的字符数组。你能告诉我怎么解决这个问题吗 #include <iostream> #include <cstring> #include <vector> using namespace std; class Cube { public: char *str;

我想知道为什么下面的程序在运行程序时会出现错误“double free or corruption(fasttop)”。我知道我可以用字符串代替字符数组。但是我想使用具有动态内存分配的字符数组。你能告诉我怎么解决这个问题吗

#include <iostream>
#include <cstring>
#include <vector>
using namespace std;

class Cube
{
public:
    char *str;

    Cube(int len)
    {
        str = new char[len+1];
    }

    Cube(const Cube &c)
    {
        str = new char[strlen(c.str) + 1];
        strcpy(str, c.str);
    }   
    ~Cube()
    {
        delete [] str;
    }
};

int main()
{
    vector <Cube> vec;

    for (int i = 0; i < 10; i++)
    {
        char in [] = "hello !!";
        Cube c(strlen(in)+1);
        strcpy(c.str, in);
        vec.push_back(c);
    } 

    int i = 0;
    for ( vector<Cube>::iterator it = vec.begin(); it < vec.end(); )
    {
        cout << it->str << endl;
        i++;
        if (i % 2 == 0)
            it = vec.erase(it);
        else
            it++;
    }


    for ( vector<Cube>::iterator it = vec.begin(); it < vec.end(); it++)
    {
        cout << it->str << endl;
    }
    return 0;    
}
#包括
#包括
#包括
使用名称空间std;
类立方体
{
公众:
char*str;
立方体(内部透镜)
{
str=新字符[len+1];
}
多维数据集(常量多维数据集和c)
{
str=新字符[strlen(c.str)+1];
strcpy(str,c.str);
}   
~Cube()
{
删除[]str;
}
};
int main()
{
向量向量机;
对于(int i=0;i<10;i++)
{
[]中的字符=“你好!!”;
立方体c(strlen(in)+1);
strcpy(c.str,in);
向量推回(c);
} 
int i=0;
对于(vector::iterator it=vec.begin();it你忘了为你的类定义操作符了。这是三巨头的规则(复制构造函数、dtor、赋值都必须定义)。

如果有问题,不要这样做:

#include <iostream>
#include <string>
#include <vector>
using namespace std;

class Cube
{
public:
    string str;

    Cube(const string& s) : str(s) { }
};

int main()
{
    vector <Cube> vec;

    for (int i = 0; i < 10; i++)
    {
        char in [] = "hello !!";
        vec.push_back(Cube(in));
    } 

    int i = 0;
    for ( vector<Cube>::iterator it = vec.begin(); it < vec.end(); )
    {
        cout << it->str << endl;
        i++;
        if (i % 2 == 0)
            it = vec.erase(it);
        else
            it++;
    }


    for ( vector<Cube>::iterator it = vec.begin(); it < vec.end(); it++)
    {
        cout << it->str << endl;
    }
    return 0;    
}
#包括
#包括
#包括
使用名称空间std;
类立方体
{
公众:
字符串str;
多维数据集(常量字符串&s):str(s){}
};
int main()
{
向量向量机;
对于(int i=0;i<10;i++)
{
[]中的字符=“你好!!”;
向量推回(立方体(in));
} 
int i=0;
对于(vector::iterator it=vec.begin();itn.m.已经给出了一个很好的答案,但我发现这个问题很有趣,所以我决定试着更好地理解它

当您对迭代器的第一项(我们称之为
item0
)调用
erase()
时,迭代器的作用如下:它使用类的
=
操作符执行
item0=item1
。然后删除
item1

如果您不定义自己的
=
操作符,我认为它只需将对象的内存从
item1
复制到
item0
,因此
item0
item1
将临时指向同一个字符串。然后当
item1
被删除时,该字符串将被释放,留下
item0
>处于无效状态,因为它有一个指向已释放内存的指针

下面是一些简单的测试代码,它再现并说明了问题:

#include <cstring>
#include <vector>
#include <stdio.h>
using namespace std;

class Cube
{
public:
    char * str;

    Cube(const Cube &c) { set(c.str); }
    Cube(const char * s) { set(s); }
    ~Cube() { clear(); }  // is "delete []" necessary?  not sure

#if 1    // change to 0 to cause a bug
    void operator=(const Cube &c)
    {
        clear();   // necessary to avoid memory leaks
        printf("operator=\n");
        set(c.str);
    }
#endif

private:
    void set(const char * s)
    {
        str = new char[strlen(s) + 1];
        printf("allocated %p for %s\n", str, s);
        strcpy(str, s);
    }

    void clear()
    {
        if (str)
        {
             printf("freeing %p: %s\n", str, str);
             delete str;
        }
    }
};

int main(int argc, char ** argv)
{
    printf("== CREATING VECTOR ==\n");
    vector <Cube> vec;
    vec.push_back(Cube("octopus"));
    vec.push_back(Cube("squid"));

    printf("== BEGINNING ITERATION ==\n");
    vector<Cube>::iterator it = vec.begin();
    printf("First entry is %p %s\n", it->str, it->str);
    it = vec.erase(it);
    printf("Second entry is %p %s\n", it->str, it->str);  // this prints garbage if Cube has no = operator
    return 0;    
}

我用MinGW在Windows中编译并运行了这段代码。我使用的命令是
g++-Wl,--enable auto import test.cpp&&a.exe

在Windows上用MinGW编译并运行这段代码时,我没有遇到任何这样的错误。你在使用什么编译器?我在Ubuntu上使用g++。我重载了赋值运算符。现在它工作正常了。好的。是的,当我运行我的程序时,我得到了损坏的数据,但是添加赋值运算符似乎可以解决这个问题。从c++引用:在向量的末尾,在它当前的最后一个元素之后添加一个新元素。这个新元素的内容初始化为x的副本。非常好!!我实现了赋值运算符(运算符=)非常好用。非常感谢!!!
== CREATING VECTOR ==
allocated 00350F98 for octopus
allocated 00350FB8 for octopus
freeing 00350F98: octopus
allocated 00350F98 for squid
allocated 00350FD8 for squid
allocated 00350FE8 for octopus
freeing 00350FB8: octopus
freeing 00350F98: squid
== BEGINNING ITERATION ==
First entry is 00350FE8 octopus
freeing 00350FE8: octopus
operator=
allocated 00350F98 for squid
freeing 00350FD8: squid
Second entry is 00350F98 squid
freeing 00350F98: squid