[英]Getting a memory leak from dynamically allocated arrays
我正在嘗試編寫一個可以反轉用戶輸入字符串的程序。 如果他們輸入“ book”,則應返回“ koob”。 我必須調用函數reverseit(char * inputString,char * outputString)並在其中編寫我的算法。
我一切正常,但最后返回一個malloc錯誤
:malloc: *** error for object 0x7fff5c8a5bc0: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
Abort trap: 6
我寫的代碼:
void reverseit(char *inputString, char* outputString);
int main()
{
char input[100];
cin.getline(input, 10);
int lenn = strlen(input);
char* usrinput = new char[lenn+1];
usrinput = input;
int len = strlen(usrinput);
char* inputString = new char[len+1];
inputString = usrinput;
char* outputString = new char[len+1];
reverseit(inputString, outputString);
for (int o = 0; o < len; o++)
{
cout << outputString[o];
}
cout << endl;
delete [] usrinput;
delete [] inputString;
delete [] outputString;
return 0;
}
void reverseit(char *inputString, char *outputString)
{
size_t length = strlen(inputString);
char temp;
int k = 0;
for(int i = length - 1; i >= 0 ; i--)
{
temp = inputString[i];
outputString[k] = temp;
k++;
}
}
有幾個限制實際上使這比實際要困難得多,因為除兩個char指針外,不允許我將任何其他變量調用為反向變量。
我的具體問題是,如果要刪除所有動態數組,內存泄漏仍將如何發生,是否會因為我沒有為每個數組輸入正確的大小而發生泄漏? 謝謝
usrinput = input;
inputString = usrinput;
要復制字符串,您需要復制每個char
,而不僅僅是重新分配指針。 使用=
會丟棄動態分配的內存(這是內存泄漏),並使所有指針指向內存中的同一位置。 這意味着usrinput
和inputString
最終都指向input
,因此由於沒有為new
分配input
,最后的delete[]
調用失敗。
strcpy(userinput, input);
strcpy(inputString, usrinput);
您對usrinput
的input
設置不正確。 input
的類型為char[]
而usrinput
的類型為char *
。 當您執行此操作時,它usrinput
重新指向由new()[]
運算符分配的另一個存儲位置。
現在,當您嘗試delete[]
,變量將指向靜態分配的char[]
類型,而不是動態分配的類型。
int main(){
char input[100]; // Statically Allocated
cin.getline(input, 10);
int lenn = strlen(input);
char* usrinput = new char[lenn+1]; // DYNAMICALLY allocated
usrinput = input; // setting statically allocated into variable that
// previously held address of dynamically allocated
// here is where your dynamic pointer gets LOST
int len = strlen(usrinput);
char* inputString = new char[len+1]; // Another Dynamic Allocation
inputString = usrinput; // This WOULD be OK except that now you are losing the
// where inputString used to point to which was
// dynamically allocated
char* outputString = new char[len+1];
reverseit(inputString, outputString);
for (int o = 0; o < len; o++)
{
cout << outputString[o];
}
cout << endl;
delete [] usrinput; // usrinput now doesn't point to a dynamically
// allocated space in memory, neither does inputString
delete [] inputString;
delete [] outputString;
return 0;
}
問題是這些行:
usrinput = input;
/* ... */
inputString = usrinput;
這不是復制字符串的正確方法。 使用strcpy()
代替:
strcpy(usrinput, input);
由於您更改了usrinput
的值, usrinput
您在與使用new[]
分配的指針不同的指針(特別是堆棧分配的數組input
)上調用delete[]
new[]
。
不能通過將一個指針分配給另一個來復制字符數組中包含的字符串。 您需要使用諸如strcpy
類的函數來搜索指針所指向的內存,直到它到達空終止符( '\\0'
),然后將內容復制到目標所指向的內存中。
例:
// Initialize an array of characters which contain the string "Foo bar\0";
char input[] = "Foo bar";
// Allocate a character array on the heap and assign it to the pointer pDest
char *pDest = new char[100];
// Reassign the pointer to the first element of input
pDest = input;
delete [] pDest; // Oops: Deleting the first element of input!
相反,您應該這樣做:
char input[] = "Foo bar";
char *pDest = new char[100];
// Copy all chars in the memory at input to the memory pointed to by pDest
strcpy(pDest, input);
delete [] pDest; // pDest still points to the dynamic memory, everything's fine
請注意,使用strcpy可能很危險,它只會將找到的所有內容復制到到達終止null的位置,直到目的地為止,它不會(無法!)檢查目的地是否足夠大。 在您的示例中,您已經通過使用strlen避免了這種情況,這很好。 只是作業無法按照您的想法工作。
除了此錯誤,您的代碼中還有其他可以改進的地方:
getline
獲取用戶輸入,為該用戶輸入的strlen + 1
分配一個新數組就可以了,您可以將這兩個變量都傳遞給reverseit(記住要添加reverseit
末尾的'\\0'
分隔符。 reverseit
使用臨時char
,只需將inputString[i]
直接分配給outputString[k]
i
和k
都放入for
聲明中,而不必以其他方式處理k
cout
可以處理char*
形式的字符串,您不需要循環就可以將結果寫入控制台,只需將cout << outputString
寫入即可 使用std::string
類可以更輕松地在C ++中處理字符串,但是我想這是某種家庭作業,您必須堅持基礎知識。
您正在釋放堆棧中的數組:
char input[100];
...
usrinput = input;
...
delete [] usrinput;
我不完全確定您要在這里完成什么,但肯定不是您在做什么。 如果要分配的內存將字符串的值保存在堆棧上,則必須執行以下操作:
my_buffer[100];
set_my_buffer(my_buffer);
char *my_allocated_buffer = new char [100];
strncpy(my_allocated_buffer, my_buffer, 100);
您分配了新的內存位置,但是將指針重新分配回了原始位置。
例:
int * pointer1 = new int[1];
pointer1[0] = 10;
int * pointer2 = new int[1];
pointer2[0] = 20;
cout << pointer2[0]; // 20
pointer2 = pointer1;
cout << pointer2[0]; // 10
cout << pointer1[0]; // 10
delete [] pointer2;
cout << pointer1[0]; // Oh no! Garbage Value! But we didn't delete pointer1 did we?
delete [] pointer1; // FATAL ERROR!
此代碼的問題在於,當指針2 =指針1時,它僅為指針2提供了指針1的地址。 它沒有拷貝任何值了。 這也意味着分配給指針2的原始空間永遠處於混亂狀態。 從未釋放。 這是導致您的代碼行出現問題的原因:
char* usrinput = new char[lenn+1];
usrinput = input;
您要復制所有值。 使用strcpy()
strcpy(usrinput, input)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.