2012-02-11 48 views
1

對於我的家庭作品,我需要用C++編寫String對象。如何避免我的方法內存泄漏?

其中一種方法是

void concatenate(String *s) 

但是,當我檢查我的對象,具有Valgrind的,還有在我的代碼中的內存泄漏。下面是方法:

// add s's str to this _str 
void String::concatenate(String *s) 
{ 
    char * conc; 
    int conc_size, i, j; 

    conc_size = _len + s->_len; 

    conc = new char[conc_size]; // line 39 

    for (i = 0; i < _len; i++) 
    conc[i] = _str[i]; 

    for (j = 0; i < conc_size || j < s->_len; i++, j++) 
    conc[i] = s->_str[j]; 

    _str = conc; // i'm assuming the problem is here 
    _len = conc_size; 
} 

這裏是Valgrind的消息:

==4706== 3 bytes in 1 blocks are definitely lost in loss record 2 of 9 
==4706== at 0x100024679: malloc (vg_replace_malloc.c:266) 
==4706== by 0x10007BF04: operator new(unsigned long) (in /usr/lib/libstdc++.6.0.9.dylib) 
==4706== by 0x10007BF96: operator new[](unsigned long) (in /usr/lib/libstdc++.6.0.9.dylib) 
==4706== by 0x100000E7E: String::concatenate(String*) (String.cpp:39) 
==4706== by 0x100001479: main (main.cpp:27) 

工程與delete [] _str;和改變構造函數:

// the empty string. 
String::String() 
{ 
    _len = 1; 

    _str = new char[_len]; 
    assert(_str); 
    _str[0] = '\0'; 
} 

// store s string in this 
String::String(char *s) 
{ 
    _len = 0; 

    int i = 0; 
    while(s[i] != '\0') 
    { 
     _len++; 
     i++; 
    } 

    _str = new char[_len]; 
    assert(_str); 

    for (i = 0; s[i] != '\0' && i < _len; i++) 
     _str[i] = s[i]; 

} 
+0

你是對的。在給'conc賦值之前,你忘記了'delete [] _str;' – Lol4t0 2012-02-11 19:26:39

+0

誰給作業去實現已經用'std :: string'正確解決的東西? – 2012-02-11 19:26:39

+0

無關的一面注意:不應該在第二個循環的條件是'我 _len'?此外,你爲什麼不使用'std :: copy'? – reima 2012-02-11 19:30:30

回答

4

您不是在處理您的會員_str的以前的內容。我假設這也是char*。所以當你告訴_str指向其他地方時,它以前指向的內存將不可訪問。

delete[] _str; 
_str = conc; 
+0

是的,_str是char * – user1090944 2012-02-11 19:28:09

+0

@ user1090944在另一個回答中,建議您在調用delete之前檢查'_str!= NULL'。這是不好的建議,因爲空指針上的「delete」是空操作。 – 2012-02-11 19:29:24

+0

我做到了,但Valgrind不喜歡它: – user1090944 2012-02-11 19:30:47

0

你的假設是對的:你指定一個新值_str指針,但分配給它的內存仍保持分配狀態。您需要在該行之前撥打delete[] _str;以釋放內存。

1

_str = conc; 

之前把

delete[] _str; 
+1

爲什麼'if(_str)'? – 2012-02-11 19:26:45

+0

刪除保證在一個空指針上是安全的,所以if(_str)是不必要的 – Zrax 2012-02-11 19:28:30

+0

嗯,你是對的。可以省略此檢查。糾正。 – mikithskegg 2012-02-11 19:28:38

1

你是對的,你要覆蓋一個新的內部指針而不將其刪除。

1

你爲什麼不delete[] _str?這是現在懸而未決。

0

我假設String::_strchar *保存數據的主指針。

因此,您必須考慮將數組刪除至_str,然後才能指定濃度。

delete[] _str; 
_str = conc; 

此外,它是爲你考慮像concatenate(const String &)的連擊方法的參數一個很好的做法。