Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 数组删除导致EXC\u错误\u访问错误_C++_Arrays_Delete Operator - Fatal编程技术网

C++ 数组删除导致EXC\u错误\u访问错误

C++ 数组删除导致EXC\u错误\u访问错误,c++,arrays,delete-operator,C++,Arrays,Delete Operator,我有一个类Foo定义如下: class Foo { public: Foo(int num); Foo(const Foo& other); ~Foo(); Foo& operator=(const Foo& other); ... private: string *fooArray; void clearMemory(); ... } Foo::Foo(int num) { fooAr

我有一个类Foo定义如下:

class Foo
{
  public:
    Foo(int num);
    Foo(const Foo& other);
    ~Foo();

    Foo& operator=(const Foo& other);
    ...

  private:
    string *fooArray;
    void clearMemory();
    ...
}

Foo::Foo(int num)
{
    fooArray = new string[num];
}

Foo::Foo(const Foo& other)
{
    *this = other;
}

Foo::~Foo()
{
    clearMemory();
}

Foo& operator=(const Foo& other)
{
    clearMemory();
    fooArray = new string[other.size]; // size is a private variable
    memcpy(fooArray, other.fooArray, other.size * sizeof(string));
}

void Foo::someOtherFooFuncion(int newNum)
{
    clearMemory(); // crash with Visual Studio, does not crash with g++, but g++ also
                   // crashes when destructor is called
    fooArray = new string[newNum];
}

void Foo::clearMemory()
{
    if(fooArray != NULL)
    {
        delete[] fooArray; // sometimes it crashes here with g++; it always crashes when
                           // compiling in Visual Studio
        fooArray = NULL;
    }
}
//                      src_begin             src_end           dest
std::uninitialized_copy(other.array, other.array + other.size, array);
正如代码注释中所指出的,它有时会让我崩溃。我已经试着遵循GDB中的步骤,我已经做到了

destructing Foo:
@0x7fff5fbff9b0
$26 = {
  fooArray = 0x1001009d8, 
  ...
}
然后到达delete[]fooArray,突然

Foo(49858) malloc: *** error for object 0x100100990: pointer being freed was not allocated
我不知道0x100990是从哪里来的

我意识到代码非常不完整,但我现在真的不知道从哪里开始查找错误,我想了解一些可能导致delete[]错误的提示

编辑:

添加了c'tor、d'tor和赋值运算符。我远离电脑,所以代码可能不是100%准确。不过,将值赋给fooArray并访问它们效果很好

另外,我非常希望能够提供一个可能导致delete[]抛出错误的问题的一般列表,这样我至少可以知道在代码中查找的位置

编辑2:

所以我按照Xeo的建议使用std::uninitialized_copy,现在代码运行良好,可以在g++下编译。析构函数在VisualStudio中也可以很好地工作,但是在其他FooFunction中删除fooArray会导致崩溃


还有其他想法吗

确保定义了复制构造函数和赋值运算符。他们需要为fooArray分配内存。如果您没有定义copyctor和operator=,编译器将为您生成它们。但是,编译器生成的指针只会复制fooArray指针,这可能会导致双重删除

如果您已经定义了它们,请在问题中添加相关代码


编辑:我可以看到复制构造函数没有分配内存,赋值操作符使用的是memcpy。两者都可能导致问题。

请确保定义了复制构造函数和赋值运算符。他们需要为fooArray分配内存。如果您没有定义copyctor和operator=,编译器将为您生成它们。但是,编译器生成的指针只会复制fooArray指针,这可能会导致双重删除

如果您已经定义了它们,请在问题中添加相关代码


编辑:我可以看到复制构造函数没有分配内存,赋值操作符使用的是memcpy。两者都可能导致问题。

如果定义默认构造函数,则必须将fooArray初始化为NULL,否则fooArray可能指向随机内存位置,该位置随后会被删除[]。

如果定义默认构造函数,则必须将fooArray初始化为NULL,否则,FoeSoad可能指向一个随机内存位置,然后在DECK[].</P>中使用McCPy不使用C++。 这一点我怎么强调都不过分。当C++中的一个类对象精确地被定义时,你就破坏了它的构造函数定义的类不变量,因为你正绕过那些构造函数。每次您memcpya一个std::string类时,您都会得到一个新对象,该对象与另一个对象引用相同的内存。您将得到双重删除,这将导致您的崩溃

使用std::uninitialized_copy from,如下所示:

class Foo
{
  public:
    Foo(int num);
    Foo(const Foo& other);
    ~Foo();

    Foo& operator=(const Foo& other);
    ...

  private:
    string *fooArray;
    void clearMemory();
    ...
}

Foo::Foo(int num)
{
    fooArray = new string[num];
}

Foo::Foo(const Foo& other)
{
    *this = other;
}

Foo::~Foo()
{
    clearMemory();
}

Foo& operator=(const Foo& other)
{
    clearMemory();
    fooArray = new string[other.size]; // size is a private variable
    memcpy(fooArray, other.fooArray, other.size * sizeof(string));
}

void Foo::someOtherFooFuncion(int newNum)
{
    clearMemory(); // crash with Visual Studio, does not crash with g++, but g++ also
                   // crashes when destructor is called
    fooArray = new string[newNum];
}

void Foo::clearMemory()
{
    if(fooArray != NULL)
    {
        delete[] fooArray; // sometimes it crashes here with g++; it always crashes when
                           // compiling in Visual Studio
        fooArray = NULL;
    }
}
//                      src_begin             src_end           dest
std::uninitialized_copy(other.array, other.array + other.size, array);
未经测试,因为我是用iPod写的

或者更好,只需使用std::vector而不是原始内存。您将不再需要析构函数和复制cto/赋值操作符。

在C++中不使用MeMCPY 这一点我怎么强调都不过分。当C++中的一个类对象精确地被定义时,你就破坏了它的构造函数定义的类不变量,因为你正绕过那些构造函数。每次您memcpya一个std::string类时,您都会得到一个新对象,该对象与另一个对象引用相同的内存。您将得到双重删除,这将导致您的崩溃

使用std::uninitialized_copy from,如下所示:

class Foo
{
  public:
    Foo(int num);
    Foo(const Foo& other);
    ~Foo();

    Foo& operator=(const Foo& other);
    ...

  private:
    string *fooArray;
    void clearMemory();
    ...
}

Foo::Foo(int num)
{
    fooArray = new string[num];
}

Foo::Foo(const Foo& other)
{
    *this = other;
}

Foo::~Foo()
{
    clearMemory();
}

Foo& operator=(const Foo& other)
{
    clearMemory();
    fooArray = new string[other.size]; // size is a private variable
    memcpy(fooArray, other.fooArray, other.size * sizeof(string));
}

void Foo::someOtherFooFuncion(int newNum)
{
    clearMemory(); // crash with Visual Studio, does not crash with g++, but g++ also
                   // crashes when destructor is called
    fooArray = new string[newNum];
}

void Foo::clearMemory()
{
    if(fooArray != NULL)
    {
        delete[] fooArray; // sometimes it crashes here with g++; it always crashes when
                           // compiling in Visual Studio
        fooArray = NULL;
    }
}
//                      src_begin             src_end           dest
std::uninitialized_copy(other.array, other.array + other.size, array);
未经测试,因为我是用iPod写的


或者更好,只需使用std::vector而不是原始内存。您不再需要析构函数和复制构造函数/赋值运算符。

您有默认构造函数吗?如果是的话,你能把它贴出来吗?你还记得那封信吗?为什么不使用std::vector?@MikeSeymour我有一个ctor和赋值运算符以及dtor,但不能使用vector,因为它是一个类赋值。这段代码在很多级别上都是错误的。。真的,请放弃类赋值并使用std::vector。。。或至少报废内存..:你有默认的构造函数吗?如果是的话,你能把它贴出来吗?你还记得那封信吗?为什么不使用std::vector?@MikeSeymour我有一个ctor和赋值运算符以及dtor,但不能使用vector,因为它是一个类赋值。这段代码在很多级别上都是错误的。。真的,请放弃类赋值并使用std::vector。。。或至少报废内存..:我已经定义了复制构造函数和赋值操作符,它们似乎可以找到,因为我在内存中写入它们。我将很快添加代码。我已经定义了复制构造函数和赋值运算符,a
他们似乎找到了工作,因为我在记忆中给他们写信。我将很快添加代码。嗯,我初始化了一个动态数组而不是NULL,我想它会工作得很好。嗯,我初始化了一个动态数组而不是NULL,我想它会工作得很好。嘿,非常感谢你的回答!我很快就会试试的。不幸的是,尽管我很想使用向量,但这是一个明确需要动态数组的类赋值:它起作用了!至少在g++中。当我试图运行我的代码时,Visual Studio仍然崩溃,但是:@ErrorUserName:如果没有更多的代码,将很难找出到底哪里出了问题。请创建一个,这样我们可以进一步调查。嘿,非常感谢你的回答!我很快就会试试的。不幸的是,尽管我很想使用向量,但这是一个明确需要动态数组的类赋值:它起作用了!至少在g++中。当我试图运行我的代码时,Visual Studio仍然崩溃,但是:@ErrorUserName:如果没有更多的代码,将很难找出到底哪里出了问题。请创建一个,以便我们可以进一步调查。