为什么我的析构函数显示被释放的指针未分配 C++
Why my destructor shows that pointer being freed was not allocated c++
我想实现2个数组相加,但是当析构到class SList
void operator+(SList list2) {
int totalLen = this->len + list2.len;
char** temp = new char* [totalLen];
for(int i = 0; i < len; i++) {
temp[i] = this->list[i];
}
for(int i = len, j = 0; i < totalLen; i++, j++) {
temp[i] = list2.get(j);
}
delete[] this->list;
this->list = temp;
this->len = totalLen;
cout << len << endl << endl;
}
这里是return动态数组char的get方法:
char* get(int i) {
if (i >= len) {
return "";
} else {
return list[i];
}
}
这是我的 class SList 私有变量:
private:
char** list;
int len;
char* generateString(){
char* str;
int n = rand() % 20 + 1;
str = new char[n + 1];
for(int i = 0; i < n; i++) {
str[i] = 'a' + rand()%26;
}
str[n] = '[=12=]';
return str;
};
~SList() {
delete[] list;
}
它总是在析构函数上显示 malloc 错误。
malloc: *** error for object 0x105007410: pointer being freed was not allocated
malloc: *** set a breakpoint in malloc_error_break to debug
请帮忙!我仔细检查了我在动态分配数组上的删除方法,但它总是显示这个错误。
我已经尝试检查其他函数的其他删除,但是 none 其中出现了相同的 malloc 错误。我试图评论析构函数方法,一切正常。但我真的需要在这里有析构函数方法。我希望对 c++ 有更多专业知识的人可以帮助我修复这个 malloc 错误,并解释我哪里出错了。
不管实现的其他细节是什么,当您使用称为“ragged array”的数据结构时,析构函数是不正确的,即 list
是指向数组的指针指针。 delete[]
会释放指针数组,但不会释放其元素指向的 char
数组。你必须这样做:
~SList() {
if(!list) return; // if we cannot guarantee that list isn't
// nullptr we have to check it,
// or result of list[i] would be undefined.
for(int i = 0; i < len; i++)
delete[] list[i];
delete[] list;
}
并且您必须确保这些指针中的任何一个都由 new
表达式初始化或等于 nullptr
.. 它不会自行发生。您必须确保在施工和所有操作期间。你没有表现出来。在那里寻找错误。
方法 get()
是一个等待发生的灾难并且是 ill-formed,即它不遵循 C++ 规则。字符串文字 ""
returns const char*
,总是相同的,并且语句 return "";
是不正确的——尽管一些编译器只对此发出警告。它不能被 delete
.
释放
char* get(int i) {
if (i >= len) {
return nullptr; // "" - is not safe
} else {
return list[i];
}
}
删除一个 nullptr
是安全的 no-op。删除 new
未 return 编辑的内容是一场灾难。
加法运算符按值取 list2
,这意味着必须执行正确的复制操作。你也没有给他们看。默认实现只会复制一个指针,而本地副本的销毁会释放原来通过上面的 ~SList()
使用的内存。运算符必须 return 结果对象,不应修改 this
指向的对象。您实施了 operator+=
。按照你的方式,它会像
a+b; // a now contains result of concatenation.
使用起来很奇怪。正确的运算符是
SList operator+(SList& list2);
一般来说,处理某些资源所有权的对象,在我们的例子中是动态内存,必须实现特定的一组特殊成员函数:
~SList();
SList(const SList& other);
SList(SList&& other); // move copy, source is a temporal.
SList& operator=(const SList& other);
SList& operator=(SList&& other); // move assignment
如果做对了,您就可以安全地完成 c = a + b;
作业了。
请注意,如果您通过引用传递参数,则必须考虑到赋值运算符的参数未引用 this
指向的对象,如果引用则相应地采取行动。否则你会破坏它并丢失原始数据。另一方面,由于成本和内存占用量增加,复制参数过多且 user-unfriendly。 n-element 和 m-element 数组的串联预计会有 n+m
个元素的内存占用,而不是 n+2*m
.
我想实现2个数组相加,但是当析构到class SList
void operator+(SList list2) {
int totalLen = this->len + list2.len;
char** temp = new char* [totalLen];
for(int i = 0; i < len; i++) {
temp[i] = this->list[i];
}
for(int i = len, j = 0; i < totalLen; i++, j++) {
temp[i] = list2.get(j);
}
delete[] this->list;
this->list = temp;
this->len = totalLen;
cout << len << endl << endl;
}
这里是return动态数组char的get方法:
char* get(int i) {
if (i >= len) {
return "";
} else {
return list[i];
}
}
这是我的 class SList 私有变量:
private:
char** list;
int len;
char* generateString(){
char* str;
int n = rand() % 20 + 1;
str = new char[n + 1];
for(int i = 0; i < n; i++) {
str[i] = 'a' + rand()%26;
}
str[n] = '[=12=]';
return str;
};
~SList() {
delete[] list;
}
它总是在析构函数上显示 malloc 错误。
malloc: *** error for object 0x105007410: pointer being freed was not allocated
malloc: *** set a breakpoint in malloc_error_break to debug
请帮忙!我仔细检查了我在动态分配数组上的删除方法,但它总是显示这个错误。
我已经尝试检查其他函数的其他删除,但是 none 其中出现了相同的 malloc 错误。我试图评论析构函数方法,一切正常。但我真的需要在这里有析构函数方法。我希望对 c++ 有更多专业知识的人可以帮助我修复这个 malloc 错误,并解释我哪里出错了。
不管实现的其他细节是什么,当您使用称为“ragged array”的数据结构时,析构函数是不正确的,即 list
是指向数组的指针指针。 delete[]
会释放指针数组,但不会释放其元素指向的 char
数组。你必须这样做:
~SList() {
if(!list) return; // if we cannot guarantee that list isn't
// nullptr we have to check it,
// or result of list[i] would be undefined.
for(int i = 0; i < len; i++)
delete[] list[i];
delete[] list;
}
并且您必须确保这些指针中的任何一个都由 new
表达式初始化或等于 nullptr
.. 它不会自行发生。您必须确保在施工和所有操作期间。你没有表现出来。在那里寻找错误。
方法 get()
是一个等待发生的灾难并且是 ill-formed,即它不遵循 C++ 规则。字符串文字 ""
returns const char*
,总是相同的,并且语句 return "";
是不正确的——尽管一些编译器只对此发出警告。它不能被 delete
.
char* get(int i) {
if (i >= len) {
return nullptr; // "" - is not safe
} else {
return list[i];
}
}
删除一个 nullptr
是安全的 no-op。删除 new
未 return 编辑的内容是一场灾难。
加法运算符按值取 list2
,这意味着必须执行正确的复制操作。你也没有给他们看。默认实现只会复制一个指针,而本地副本的销毁会释放原来通过上面的 ~SList()
使用的内存。运算符必须 return 结果对象,不应修改 this
指向的对象。您实施了 operator+=
。按照你的方式,它会像
a+b; // a now contains result of concatenation.
使用起来很奇怪。正确的运算符是
SList operator+(SList& list2);
一般来说,处理某些资源所有权的对象,在我们的例子中是动态内存,必须实现特定的一组特殊成员函数:
~SList();
SList(const SList& other);
SList(SList&& other); // move copy, source is a temporal.
SList& operator=(const SList& other);
SList& operator=(SList&& other); // move assignment
如果做对了,您就可以安全地完成 c = a + b;
作业了。
请注意,如果您通过引用传递参数,则必须考虑到赋值运算符的参数未引用 this
指向的对象,如果引用则相应地采取行动。否则你会破坏它并丢失原始数据。另一方面,由于成本和内存占用量增加,复制参数过多且 user-unfriendly。 n-element 和 m-element 数组的串联预计会有 n+m
个元素的内存占用,而不是 n+2*m
.