我想实现2个数组加法,但是当析构函数被添加到类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;
}下面是get方法,它只返回char的动态数组:
char* get(int i) {
if (i >= len) {
return "";
} else {
return list[i];
}
}下面是我的类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] = '\0';
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请帮帮我!我仔细检查了动态分配数组上的delete方法,但是它总是显示这个错误。
我试过检查其他函数中的其他删除,但它们都没有犯相同的malloc错误。我尝试过注释析构函数方法,一切都很好。但我真的需要用析构方法。我希望在c++方面拥有更多专业知识的人能够帮助我修复这个malloc错误,并解释我犯了什么错误。
发布于 2022-03-24 06:56:02
不管实现的其他细节是什么,在使用称为"破烂阵列“的数据结构时,析构函数都是不正确的,也就是说,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()方法是一种等待发生的灾难,是一种不符合C++规则的错误形式。字符串文本""总是返回const char*,并且语句return "";是不正确的-一些编译器只是对此发出警告。它不能被delete释放。
char* get(int i) {
if (i >= len) {
return nullptr; // "" - is not safe
} else {
return list[i];
}
}删除nullptr是一个安全的不操作。删除new没有返回的内容是一场灾难。
加法运算符按值取list2,这意味着必须实现正确的复制操作。你也没给他们看。默认实现只是复制一个指针,本地副本的销毁将释放原来通过上面的~SList()使用的内存。操作符必须返回结果对象,不应该修改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指出的对象,如果它们引用了对象,则相应地执行操作。否则你会毁了它并丢失原始数据。另一方面,由于成本和内存占用增加,复制参数过多且对用户不友好。N元素和m元素数组的级联应该具有n+m元素的内存占用,而不是n+2*m。
https://stackoverflow.com/questions/71597537
复制相似问题