[英]std::string::c_str() overwrittes the previous one returned by a function
我不明白當文本大小相等時指針如何相同。 似乎firstStringObj :: c_str()覆蓋了前一個的指針。
#include <iostream>
#include <string>
#include <string>
#include <stdio.h>
std::string getConstCharAndModifyItWithANewString( const char* constchar )
{
std::string stringAtStack( constchar );
stringAtStack += "::isModified";
return stringAtStack;
}
int main()
{
const char* firstConstCharPointer = getConstCharAndModifyItWithANewString("Hi!").c_str();
std::string firstStringObj = "Hi+";
printf(" firstConstCharPointer(%s)(%p)\nfirstStringObj(%s)(%p)\n\n", firstConstCharPointer,firstConstCharPointer, firstStringObj.c_str(), firstStringObj.c_str() );
}
輸出:firstConstCharPointer(Hi +)(0x4593eb8)firstStringObj(Hi +)(0x4593eb8)
指針在您的平台上是相同的,因為firstConstCharPointer
是一個懸空的指針,它指向已釋放的內存。
這是因為在賦值表達式const char* firstConstCharPointer = ...;
之后, getConstCharAndModifyItWithANewString
返回的std::string
被銷毀了const char* firstConstCharPointer = ...;
。
因此,當您創建一個新的std::string
對象時,編譯器選擇使用與以前的std::string
對象相同的內存位置,因此指針是相同的。
例如,在我的平台上,指針是相同的,並且它們不在Ideone中 。
您具有經典的不確定行為。 由於%s
printf
嘗試取消引用firstConstCharPointer
。 firstConstCharPointer
指向已被破壞的數據,因為與該指針的生命周期相關聯的std::string
在分配后停止:
const char* firstConstCharPointer = getConstCharAndModifyItWithANewString("Hi!").c_str();
// temporary std::string returned from getConstCharAndModifyItWithANewString destroyed, pointer becomes dangling.
從c_str()獲得的指針可能通過以下方式無效:
- 將對字符串的非常量引用傳遞給任何標准庫函數,或者
- 在字符串上調用非常量成員函數,但不包括operator [],at(),front(),back(),begin(),rbegin(),end()和rend()。
因此,您使用的指針無效,因為析構函數是一個非常量成員函數,因此未在上面列出。
您的函數返回一個臨時的 std::string
對象。 分配firstConstCharPointer
變量並完成表達式后,該臨時對象將被銷毀,釋放其分配的內存塊,並使該變量指向已釋放的內存。 這稱為懸空指針 。
然后firstStringObj
分配一個新的內存塊,該內存塊恰好正在重用temp std::string
先前已分配和釋放的同一內存塊。 因此,懸空的指針恰好再次指向有效內存。 這就是為什么您的printf()
語句能夠為兩個字符串顯示相同的內存地址和內容的原因。
但這是未定義的行為 。 每次分配的內存塊完全由字符串的Allocator
決定。 第二個std::string
可以很容易地分配了一個完全不同的內存塊,然后當它試圖取消引用仍然指向無效內存的懸空指針時,代碼更有可能崩潰,或者至少出現打印垃圾。
為了使代碼正常工作,您需要將firstConstCharPointer
更改為std::string
對象,以便正確復制臨時std::string
,例如:
#include <iostream>
#include <string>
#include <cstdio>
std::string getConstCharAndModifyItWithANewString( const char* constchar )
{
std::string stringAtStack( constchar );
stringAtStack += "::isModified";
return stringAtStack;
}
int main()
{
const std::string firstConstStringObj = getConstCharAndModifyItWithANewString("Hi!");
std::string secondStringObj = "Hi!";
std::printf(" firstConstStringObj(%s)(%p)\nsecondStringObj(%s)(%p)\n\n", firstConstStringObj.c_str(), firstConstStringObj.c_str(), secondStringObj.c_str(), secondStringObj.c_str());
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.