2013-03-10 103 views
1

我已經執行了下面的代碼,它完美地工作。既然是關於指針,我只想確定一下。雖然我確信將char *分配給字符串會生成副本,即使我刪除了char *,字符串var也會保留該值。將字符分配給字符串變量後刪除char *

#include <stdio.h> 
    #include <string.h> 
    #include <string> 
    #include <iostream> 

    int main() 
    { 
     std::string testStr = "whats up ..."; 
     int strlen = testStr.length(); 
     char* newCharP = new char[strlen+1]; 
     memset(newCharP,'\0',strlen+1); 
     memcpy(newCharP,testStr.c_str(),strlen); 


     std::cout << " :11111111 : " << newCharP << "\n"; 
     std::string newStr = newCharP ; 

     std::cout << " 2222222 : " << newStr << "\n"; 
     delete[] newCharP; 
     newCharP = NULL; 

     std::cout << " 3333333 : " << newStr << "\n"; 
    } 

我只是改變我公司項目中的一些代碼和char *在C++函數之間傳遞。 char *指針已被複制到字符串中,但char *在函數結尾處被刪除。我找不到任何具體原因。所以我只是刪除了char *,只要它被複制到一個字符串中。這會造成任何問題......?

P.S:我已經在Codereview中提過這個問題,但我有建議將它移到SO。所以我已經把它貼上標籤並在這裏發佈這個問題。

回答

5

只要newChar指向一個以空字符結尾的字符串,並且它本身不爲null,則沒有問題。

std::string有構造函數,允許從const char*隱式構造。它會複製輸入const char *所表示的字符串,因此它在假設char*是空終止字符串的情況下工作,因爲沒有其他方法可以知道要將多少個字符複製到字符串自己的數據存儲中。此外,標準實際上不允許使用NULL指針。

9

不,因爲std::string複製了您的char*的內容,因此您可以在不再需要時自由刪除它。

1

的代碼是好的,如果你看看std::basic_stringhere的構造函數,你就可以推斷出std::string有兩個有趣的構造函數在這裏:

(4) string(char const*, 
      size_type count, 
      Allocator const& alloc = Allocator()); 

(5) string(char const* s, 
      Allocator const& alloc = Allocator()); 

兩個執行復制,並且首先讀取準確count個字符,而第二個字符會讀取,直到遇到NUL字符。


話雖這麼說,我積極鼓勵你在這裏使用動態分配。如果您想要使用臨時緩衝區,請考慮使用std::vector

#include <stdio.h> 
#include <string.h> 
#include <string> 
#include <iostream> 

int main() 
{ 
    std::string testStr = "whats up ..."; 
    unsigned strlen = testStr.length(); 

    std::vector<char> buffer(strlen+1); 

    memset(&buffer[0],'\0',strlen+1); 
    memcpy(&buffer[0], testStr.c_str(), strlen); 

    std::cout << " :11111111 : " << &buffer[0] << "\n"; 

    std::string newStr(&buffer[0]); 

    std::cout << " 2222222 : " << newStr << "\n"; 

    buffer.clear(); 

    std::cout << " 3333333 : " << newStr << "\n"; 
} 

注:既vectorstring有區間的構造,從一系列的迭代器構建它們,我故意使用,以避免混亂,你被淹沒忍住了。只要知道你可以使用它們來避免調用memcpy並冒着緩衝區溢出的風險。

+0

感謝馬特,實際上char *是從另一個函數傳遞的。就像我說我正在處理一些舊的代碼,我不能繼續和改變所有函數調用中的參數。我們的代碼庫相當大。這些char *的刪除在函數的許多部分中執行,每個只在一些條件下執行一次。雖然我不喜歡代碼重複,所以我只是將char *複製到字符串中,並在函數本身的開頭刪除了char *。 – 2013-03-10 16:11:58

+1

@ManikandarajS:哼!我知道你的痛苦,我必須自己處理一些陰沉的應用程序:(在這種情況下,你正在朝着正確的方向努力限制「感染」並調整你必須處理的代碼,以便它變得更好! – 2013-03-10 16:26:43

相關問題