double free or corruption,为什么会出现这个?
Double free or corruption, why does this appear?
我几乎完成了我的智能指针(我知道......)所以我将它上传到我大学的网站,该网站对我的代码运行了一些自动化测试。许多测试有两处错误:
- 超出内存或时间限制
- 内存访问问题(即空指针)
问题是我不知道正在执行哪种测试。我能够读取我所做的自动化测试的标准输出,这是写在那里的:
In instantiation of ‘my_pointer<T>::my_pointer() [with T = tester]’:
error: no matching function for call to ‘tester::tester()’
note: candidates are:
tester::tester(my_pointer<tester>)
candidate expects 1 argument, 0 provided
tester::tester(const tester&)
candidate expects 1 argument, 0 provided
所以我猜出于某些奇怪的原因它不会调用我的 my_pointer() 构造函数?
这是我的智能指针 class:
template<class T>
class my_pointer {
T* raw_pointer;
public:
my_pointer() {
raw_pointer = new T();
raw_pointer->incRefCnt();
}
my_pointer(T *obj) : raw_pointer(obj) {
if(raw_pointer != NULL) raw_pointer->incRefCnt();
}
my_pointer(const my_pointer<T>& smart_pointer) : raw_pointer(smart_pointer.raw_pointer) {
if(raw_pointer != NULL) raw_pointer->incRefCnt();
}
T& operator*() {
return *raw_pointer;
}
T* operator->() {
return raw_pointer;
}
operator T*() {
return raw_pointer;
}
my_pointer<T> &operator=(const my_pointer<T> &smart_pointer) {
if(this != &smart_pointer && raw_pointer != NULL) {
/** if this was the last reference to the given memory address */
if (raw_pointer->decRefCnt() == 0) {
delete raw_pointer;
}
raw_pointer = smart_pointer.raw_pointer;
raw_pointer->incRefCnt();
}
return *this;
}
bool operator== (const T* pointer) {
return raw_pointer == pointer;
}
bool operator!= (const T* pointer) {
return raw_pointer != pointer;
}
bool operator== (const my_pointer<T> &smart_pointer) {
return raw_pointer == smart_pointer.raw_pointer;
}
bool operator!= (const my_pointer<T> &smart_pointer) {
return raw_pointer != smart_pointer.raw_pointer;
}
~my_pointer() {
if(raw_pointer->decRefCnt() == 0 && raw_pointer != NULL) {
delete raw_pointer;
}
}
};
这是一篇class,其中引用可统计:
class refcounted {
private:
int count;
public:
refcounted() : count(0) { }
int incRefCnt() {
return ++count;
}
int decRefCnt() {
return --count;
}
};
你能看出代码有什么问题吗?提前致谢!
您正在无条件地删除析构函数中的原始指针。这是错误的。您必须减少引用计数,并且只有在它变为零时才删除。
您还在多个地方调用了 raw_pointer->incRefCnt();
而没有检查 raw_pointer
是否为 NULL
。
我发现你的代码有两个问题:
在 operator=() 中:在取消引用 raw_pointer
之后检查 if(raw_pointer != NULL)
(在上面的行中)。你应该撤销支票。
在析构函数中:你不应该先调用decRefCnt()
,如果引用计数已经降为零才删除raw_pointer
吗?
由于您在 operator=()
和 ~my_pointer()
中需要几乎相同的代码来减少引用计数并在需要时删除 raw_pointer (AFAICS),因此提取它似乎更实用新方法的功能并从两个地方调用它。
我几乎完成了我的智能指针(我知道......)所以我将它上传到我大学的网站,该网站对我的代码运行了一些自动化测试。许多测试有两处错误:
- 超出内存或时间限制
- 内存访问问题(即空指针)
问题是我不知道正在执行哪种测试。我能够读取我所做的自动化测试的标准输出,这是写在那里的:
In instantiation of ‘my_pointer<T>::my_pointer() [with T = tester]’:
error: no matching function for call to ‘tester::tester()’
note: candidates are:
tester::tester(my_pointer<tester>)
candidate expects 1 argument, 0 provided
tester::tester(const tester&)
candidate expects 1 argument, 0 provided
所以我猜出于某些奇怪的原因它不会调用我的 my_pointer() 构造函数? 这是我的智能指针 class:
template<class T>
class my_pointer {
T* raw_pointer;
public:
my_pointer() {
raw_pointer = new T();
raw_pointer->incRefCnt();
}
my_pointer(T *obj) : raw_pointer(obj) {
if(raw_pointer != NULL) raw_pointer->incRefCnt();
}
my_pointer(const my_pointer<T>& smart_pointer) : raw_pointer(smart_pointer.raw_pointer) {
if(raw_pointer != NULL) raw_pointer->incRefCnt();
}
T& operator*() {
return *raw_pointer;
}
T* operator->() {
return raw_pointer;
}
operator T*() {
return raw_pointer;
}
my_pointer<T> &operator=(const my_pointer<T> &smart_pointer) {
if(this != &smart_pointer && raw_pointer != NULL) {
/** if this was the last reference to the given memory address */
if (raw_pointer->decRefCnt() == 0) {
delete raw_pointer;
}
raw_pointer = smart_pointer.raw_pointer;
raw_pointer->incRefCnt();
}
return *this;
}
bool operator== (const T* pointer) {
return raw_pointer == pointer;
}
bool operator!= (const T* pointer) {
return raw_pointer != pointer;
}
bool operator== (const my_pointer<T> &smart_pointer) {
return raw_pointer == smart_pointer.raw_pointer;
}
bool operator!= (const my_pointer<T> &smart_pointer) {
return raw_pointer != smart_pointer.raw_pointer;
}
~my_pointer() {
if(raw_pointer->decRefCnt() == 0 && raw_pointer != NULL) {
delete raw_pointer;
}
}
};
这是一篇class,其中引用可统计:
class refcounted {
private:
int count;
public:
refcounted() : count(0) { }
int incRefCnt() {
return ++count;
}
int decRefCnt() {
return --count;
}
};
你能看出代码有什么问题吗?提前致谢!
您正在无条件地删除析构函数中的原始指针。这是错误的。您必须减少引用计数,并且只有在它变为零时才删除。
您还在多个地方调用了 raw_pointer->incRefCnt();
而没有检查 raw_pointer
是否为 NULL
。
我发现你的代码有两个问题:
在 operator=() 中:在取消引用
raw_pointer
之后检查if(raw_pointer != NULL)
(在上面的行中)。你应该撤销支票。在析构函数中:你不应该先调用
decRefCnt()
,如果引用计数已经降为零才删除raw_pointer
吗?
由于您在 operator=()
和 ~my_pointer()
中需要几乎相同的代码来减少引用计数并在需要时删除 raw_pointer (AFAICS),因此提取它似乎更实用新方法的功能并从两个地方调用它。