中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

C++中string轉換為char*類型返回后亂碼怎么辦

發布時間:2020-07-07 13:40:46 來源:億速云 閱讀:285 作者:清晨 欄目:開發技術

這篇文章主要介紹C++中string轉換為char*類型返回后亂碼怎么辦,文中介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們一定要看完!

問題來源:

在寫二叉樹序列化與反序列化時發現序列化函數為char* Serialize1(TreeNode *root)  其函數返回類型為char*,但是我在實現的過程中為了更方便的操作添加字符串使用的是C++中string類型的變量,這就導致我最后得到的結果res是string類型,若是要返回需要轉化為char *類型。而等我將string類型轉為char*后返回在主函數中就成了亂碼。

先直接說最后的解決辦法:

第一種:定義一個char數組,數組長度為stringlength+1,將string的內容依次賦值給char數組,最后加上'\0' ,然后返回char數組名就行了。

第二種:將string定義為類的成員變量

就貼第一種方法的代碼

char *result = new char[res.length() + 1];  //定義需要返回的result對象
for (int i = 0; i < res.length(); ++i)
{
   result[i] = res[i];    //將string類型的res內容都放到result內
}
result[res.length()] = '\0';  //加上結束符\0

再說說我嘗試的方法

嘗試1:

一開始我是直接定義char *result=&res[0];想要通過這個語句直接返回這個string類型變量的首地址,但是失敗了,在主函數中的結果變量是亂碼 "葺葺葺葺葺葺葺葺葺葺"

嘗試2:

于是我開始思考可能的原因

1.考慮到局部變量可能隨著函數釋放,因此導致我返回的指針指向的內容隨著函數一起釋放導致了亂碼,但一想到平時寫的函數都是正常返回的,所以這個我很快否決了,但最后發現這個思路是對的。至于平常寫的函數都是正常返回則是因為沒有涉及到類型轉換。

2.通過VS的調試發現我使用的char *result=&res[0]語句返回的是res的首個元素地址,并不是res的首地址,因為string作為std封裝的數據結構除了char*這種從C吸收過來的結構還有內存分配allocate這些東西所以導致其內存地址并不像char數組那樣是首個元素地址

所以我想干脆把整個string類型的res都賦值給char *類型的result

所以我嘗試了char *result=(char*)res.data();語句,將res(res是string類型的結果)賦給result,轉換是成功的,但返回值依舊失效(且這種轉換需要自己加上\0結束符)

然后嘗試char *result=(char*)res.c_str();結果也是成功的,但返回值依舊失效。

最后嘗試,用new新建一個char數組,將res的內容全部拷貝到char數組內,然后將數組名返回,終于成功。

問題根源

通過VS調試我最終發現了問題根源所在:res所占內存隨著函數結束而被釋放

這是函數未執行完的調試界面

C++中string轉換為char*類型返回后亂碼怎么辦

這是執行完調試界面

C++中string轉換為char*類型返回后亂碼怎么辦

很明顯:res沒有了,在函數執行完畢后res內存也跟著被釋放了而char數組result卻仍然存在。他們的不同點在哪:result是返回值

我們知道函數的函數棧知識點,棧內存放著函數入口地址,局部變量,返回地址等,我猜測result作為要被返回的對象其內存空間應該是不隨著函數一起被釋放的,也就是主函數內的返回值應該還是用那塊內存,經過測試這個結論是對的。主函數中的變量的確是使用返回值那塊內存。

到這里就發現了,雖然執行char* result=(char*)res.c_str()語句能讓result內是完整的結果內容(也就是轉換完成),但result會隨著string類型的res的釋放而導致char*類型的result所指向的內存空間內容全部清空。最后雖然返回了result所指的空間但里面的內容早就被清空了。就好比把內存比作一塊地,res先在其上面蓋了一座房子,而使用上面轉換語句后result也是房子的主人,這下房子有了兩個主人,他們都能對房子進行操作。正因為他們都能進行操作,當他們所屬函數結束也就是res大限到來之時,res將自己建立的房子銷毀了。那么result也就沒有房子可住了。也就是他們公用的那片內存被初始化,這時主函數雖然收到了返回地址但那片地址已經沒有內容了。也就導致亂碼了。

到這里,問題的根源就知道了,那么解決方法也就很明顯了:1.內存分離,將res和result的所屬內存地址分開。2.或者想辦法讓res所在內存不隨著函數結束而釋放.

具體實現:

第1種.上面那段new新建char*變量的代碼。為result重新開辟一段空間。

第2種.i:若在類里:將res設為類的成員變量或者static成員變量(最好不要,能成功但會有新問題出現),他們都不會隨著成員函數的結束而釋放。區別就是普通成員變量會隨著對象的釋放而釋放,static不會,它是存放在靜態存儲區

ii:若是像C這類面向過程代碼就是將res設為全局變量即可

以上是C++中string轉換為char*類型返回后亂碼怎么辦的所有內容,感謝各位的閱讀!希望分享的內容對大家有幫助,更多相關知識,歡迎關注億速云行業資訊頻道!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

福鼎市| 广宁县| 汾西县| 汝城县| 尚志市| 巴林左旗| 托克托县| 景宁| 平乡县| 锡林浩特市| 望奎县| 万全县| 大渡口区| 黔南| 全椒县| 璧山县| 望都县| 南乐县| 曲水县| 耿马| 呼伦贝尔市| 宽甸| 探索| 保德县| 鹤岗市| 秦皇岛市| 乡宁县| 永靖县| 宜君县| 遵义县| 吉水县| 抚松县| 曲水县| 鹰潭市| 伊金霍洛旗| 米林县| 达拉特旗| 云林县| 阜南县| 伊宁市| 泰顺县|