我想實作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;
}
以下是僅回傳 char 動態陣列的 get 方法:
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
請幫忙!我已經仔細檢查了動態分配陣列上的洗掉方法,但它總是顯示此錯誤。
我試圖從其他函式中檢查其他洗掉,但它們都沒有產生相同的 malloc 錯誤。我試圖評論解構式方法并且一切正常。但我真的需要在這里有解構式。我希望對 c 有更多專業知識的人可以幫助我修復這個 malloc 錯誤,并解釋我在哪一部分犯了錯誤。
uj5u.com熱心網友回復:
無論實作的其他細節是什么,當您使用稱為“不規則陣列”的資料結構時,解構式都不正確,即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];
}
}
洗掉 anullptr是一個安全的無操作。洗掉沒有回傳的東西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;作業。
Note that if you pass argument by reference you have to take in account that arguments of assigning operators aren't referencing the object pointed by this and act accordingly if they are. Otherwise you would destroy it and loose original data. On other hand copying argument is excessive and user-unfriendly due to increased cost and memory footprint. Concatenation of n-element and m-element array is expected to have memory footprint of n m elements , not n 2*m.
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/450313.html
下一篇:MYSQL8.0版本安裝失敗!
