2010-07-10 34 views
-1

我想學習C++,在這個過程中,我嘗試編寫一個函數,它獲取兩個char指針並將第二個連接到第一個連接(我知道有strcat這個)。
但是 - 我想要完成的是修改第一個參數指針,以便它指向結果。爲此,我在第一個參數中使用了對指針的引用。在C++問題中的內存釋放(Visual Studio 2010)

從函數返回之前,我想釋放第一個參數的內存,但我得到一個錯誤。

下面是代碼:

void str_cat(char*& str1, char* str2) 
{ 
if (!str1) 
{ 
    str1 = str2; 
    return; 
} 
if (!str2) 
    return; 
char * new_data = new char[strlen(str1) + strlen(str2) +1]; 
char * new_data_index = new_data; 
char * str1_index = str1; 
char * str2_index = str2; 

while(*str1_index) 
    *new_data_index++ = *str1_index++; 
while(*str2_index) 
    *new_data_index++ = *str2_index++; 
*new_data_index = NULL; 

delete str1; //ERROR HERE (I also tried delete[] str1) 

str1 = new_data; 
} 

我不明白爲什麼。
有什麼建議嗎?

感謝,
伊泰\

編輯 這裏是我如何使用

char * str1 = NULL; 
char * str2 = NULL; 
str_cat(str1, "abc"); 
str_cat(str2, "def"); 
str_cat(str1, str2); 
+0

調用代碼如何創建傳入的緩衝區? – 2010-07-10 12:53:14

+5

'我正在學習C++',然後使用'std :: string'而不是C風格的字符串。 – 2010-07-10 12:57:04

+0

@Georg Fritzsche - 我試圖使用str_cat(str1,「aaa」),但後來意識到第二個參數沒有在堆中分配,但在堆棧中,所以我將其更改爲新的char [] ...但仍然無效。 – 2010-07-10 12:57:08

回答

7

只能刪除已分配與新事物的功能 - 如果你的代碼是這樣的:

str_cat("foo", "bar"); 

這將是非法的。基本上,你的功能是完全不安全的。更好的設計是通過函數的返回值返回新的字符串。更好的是,忘掉整個想法並使用std :: string。

儘管學習使用對指針的引用是值得稱道的事情,但您應該意識到它們在C++編程中很少使用。您最好建議花時間學習使用C++標準庫的功能。

+0

我編輯了問題以顯示用法。無論如何 - 我的意思是傳遞一個空指針並在其中獲取一個值。 – 2010-07-10 13:01:46

+0

@Itay由於多種原因,它仍然無法工作。基本上這是一個不好的設計,不能在C++中安全地實現。 – 2010-07-10 13:04:15

+0

@尼爾·巴特沃斯:我得到了糟糕的設計。但仍然 - 爲什麼它不起作用? – 2010-07-10 13:07:23

3

str_cat()結果的第一呼叫str1被分配的字符串字面​​,你傳遞的地址。
隨着第三個電話這是您要deletestr1,正如尼爾指出,成爲一個問題,對於字符串文字是非法的。

+0

謝謝:) 有無論如何測試是否合法釋放內存位置? – 2010-07-10 13:08:32

+0

@Itay不,沒有,這就是爲什麼該功能的設計不好。 – 2010-07-10 13:11:46

+0

@Itay:不,這就是爲什麼你不應該使用這種人爲的方法。你可以要求調用者傳遞一個足夠大小的緩衝區,或者你總是返回一個新分配的緩衝區並記錄應該如何釋放它。或者,如前所述,不要這樣做 - 使用'std :: string','std :: vector '等人將立即擺脫所有問題。 – 2010-07-10 13:12:42