数组删除导致EXC_BAD_ACCESS错误
Array deletion giving EXC_BAD_ACCESS error
我有一个类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;
}
}
正如代码注释中所指出的,它有时会让我崩溃。我已经尝试过遵循GDB中的步骤,我已经达到了
destructing Foo:
@0x7fff5fbff9b0
$26 = {
fooArray = 0x1001009d8,
...
}
然后达到delete[] fooArray
,突然
Foo(49858) malloc: *** error for object 0x100100990: pointer being freed was not allocated
不知道0x100100990是从哪里来的。
我意识到代码非常不完整,但我现在真的不知道从哪里开始寻找错误,我想了解一些可能导致delete[]
错误的情况。
编辑:
添加了c'tor、d'tor和赋值运算符。我不在电脑上,所以代码可能不是100%准确。不过,将值分配给fooArray并访问它们也很好。
此外,我将非常感谢一个可能导致delete[]
抛出错误的问题的一般列表,这样我至少可以知道在代码中的位置。
编辑2:
因此,我遵循Xeo的建议使用std::uninitialized_copy
,现在代码运行良好,并在g++下编译。析构函数在VisualStudio中也可以正常工作,但在someOtherFooFuncion
中删除fooArray会导致它崩溃。
还有其他想法吗?
确保定义了一个复制构造函数和一个赋值运算符。他们将需要为fooArray
分配内存。如果您没有定义副本ctor和operator=
,编译器将为您生成它们。然而,编译器生成的指针只会复制fooArray
指针,可能会导致deletes
加倍。
如果您已经在定义它们,请将相关代码添加到您的问题中。
edit:我可以看到您的复制构造函数没有分配内存,而您的赋值运算符正在使用memcpy()
。两者都可能造成问题。
不要在C中使用memcpy++
我再怎么强调也不为过。当memcpy
在C++中处理类对象(确切地说是非POD)时,您正在破坏由其构造函数定义的类"不变量",因为您正是在绕过这些不变量。每次memcpy
是std::string
类时,都会得到一个新对象,该对象引用与另一个对象相同的内存。你会被双重删除,这会导致你的崩溃。
使用<algorithm>
中的std::uninitialized_copy
,如下所示:
// src_begin src_end dest
std::uninitialized_copy(other.array, other.array + other.size, array);
(未经测试,因为我是用iPod写的)
或者更好的是,只需使用std::vector
而不是原始内存。您将不再需要析构函数和复制构造函数/赋值运算符。
如果定义默认构造函数,则必须将fooArray
初始化为NULL,否则fooArray
可能指向一个随机内存位置,该位置将受到delete[]
的约束。
- 警告处理为错误这里有什么问题
- "error: no matching function for call to"构造函数错误
- boost::进程间消息队列引发错误
- C++,OpenCV,尝试显示图像时"OpenCV(4.3.0) Error: Assertion failed (size.width>0 && size.height>0)"此错误
- 有关插入适配器的错误。[错误]请求从 'back_insert_iterator<vector<>>' 类型转换为非标量类型
- QT在错误的班级中寻找空位
- vector.resize()中的分配错误
- 代码在main()中运行,但在函数中出现错误
- 释放错误后堆使用
- 获取错误:在抛出"std::bad::alloc"的实例后终止调用 what(): std::bad_alloc
- 新的 C++14 位分隔符处"Bad Character" Eclipse Oxygen 错误
- 解密文件AES_256_CBC返回"bad decrypt"错误
- OpenCV C++神经网络 predict() 函数抛出"Bad argument"错误
- cvLogPolar 导致 opencv 错误"Bad flag (parameter or structure field)"
- 生成文件'fdopen: Bad file descriptor'错误
- 来自 MSDN C++ 示例的 LDAP "The search filter is bad."错误
- 'Pre-mature EOF'和'Bad Character'错误
- 错误:在 CComVariant 中"bad variable type":循环访问 CComSafeArray 时复制
- fwrite 失败(返回 0,错误给出 "Bad address")
- Xcode4:再次"bad codegen, pointer diff"链接器错误