2016-08-25 50 views
0

我有一個需要存儲const char *的結構體供以後使用。該字符串在那時被破壞。我有到現在爲同一代碼是在C++中const char *的字符串將垃圾放在結尾

HttpRequest* send(string reply) 
    { 
      int len = strlen(reply.c_str()); 
      char *buffer = new char[len+1]; 
      strncpy(buffer, reply.c_str(), len); 
      cout << "LEN:"<<reply.length()<<endl; 
      cout << "OG:"<<reply<<endl<<"TC:"<<buffer<<endl<<"CS"<<reply.c_str()<<endl; 
      this->res.response = "test"; 
      return this; 
    }; 

res.response是的char *,我要值存儲在從我得到COUT輸出。是

LEN:5 
OG:hello 
TC:hello�������������������q{ 
CShello 

此行爲對我來說很奇怪。有人可以請解釋我做錯了什麼。此外上面的代碼顯示我使用strlen,但我在C++中也使用length()也得到了相同的結果。

另外值得一提的是,這種情況只發生在我第一次調用它之後,它會很好。

+2

[FYI]'的strlen(reply.c_str());'可以用'@NathanOliver我提到也reply.size()' – NathanOliver

+0

代替。我認爲錯誤的原因是,所以我發佈了我使用strlen的代碼的最後一個副本:) – georoot

+0

啊。我想知道爲什麼在代碼中稍後使用'length',但是你沒有使用它作爲字符串的大小。還有是你需要將字符串複製到char數組的原因嗎?由於您從未刪除緩衝區,因此您創建了內存泄漏。 – NathanOliver

回答

8

你從來不把空終止:

char *buffer = new char[len+1]; 
strncpy(buffer, reply.c_str(), len); 
buffer[len] = 0; // <-- HERE 

strncpy不添加它。

+0

非常感謝。有用。現在不能接受的答案將不得不等待12分鐘:) – georoot

+1

我不知道爲什麼人們+1誤導性的答案。如果有空間的話,'strncpy'會添加它,所以問題不會顯示缺少的代碼,但是需要將緩衝區大小傳遞給'strncpy',而不是字符串長度 – Slava

3

您對strncpy()的參數使函數誤解爲沒有空格來終止空字符,所以不會寫入。更正像

strncpy(buffer, reply.c_str(), len+1); 

在這段代碼的參數,它保證了緩衝區的長度足以存儲字符串,所以你可以簡單地使用strcpy()代替strncpy()這樣的:

strcpy(buffer, reply.c_str()); 

如果您的系統支持它,則可以使用strdup()函數。使用它,

int len = strlen(reply.c_str()); 
char *buffer = new char[len+1]; 
strncpy(buffer, reply.c_str(), len); 

可以

char *buffer = strdup(reply.c_str()); 

注意strdup()被替換的線條從C函數,它使用malloc()內部,所以你必須使用free(),不delete[],釋放內存通過strdup()分配。

1

不要使用strncpy直到你閱讀瞭解其文檔。然後不要使用它。這是一個非常專業化的功能,無需在這裏處理它的怪癖。問題中的代碼爲結果分配了足夠的空間,因此只需使用strcpy即可。

1

的問題是,這種說法

strncpy(buffer, reply.c_str(), len); 

不會將原字符串複製終止零(「\ 0」)到buffer

只有當對象包含嵌入的零時,才應使用標準C函數strlenstd::string類型的對象。否則使用類std::stringsizelength的成員函數。

代替標準C函數strncpy您可以使用標準C函數strcpy將零終止字符串複製到緩衝區中。

例如

char *buffer = new char[len+1]; 
    strcpy(buffer, reply.c_str());