標籤:

一段很有意思的代碼,你能說出為什麼結果是這樣嗎?

由於字數限制,問題在這裡:一段很有意思的C++代碼,你能說出它為什麼是這樣么? - 知乎專欄

見仁見智地說說吧。


一坨*的代碼,其中遺留了大量C語言時代的糟粕寫法,和錯誤

挨個講

  • string對象傳值

C++的string對象,不是char*,拷貝的行為是深拷貝,對於過長的字元串,是會消耗一定性能的,應該儘可能使用const string來傳遞

  • 使用了new和裸指針,而且還沒delete

鑒於這是一段示例代碼,我就不說太多了

  • 注釋中的代碼有強行把string對象轉為char*使用的痕迹

再說一遍,string對象不是char*,強轉是會出問題的,而且也觸發了C++的UB

  • 使用了危險的C式轉型

不去明確轉換操作而去使用C式轉型,各種潛在錯誤都從這裡來,針對這段代碼:

使用C式轉型從字元串字面量構造string對象

使用C式轉型將c_str()返回的const char*轉換為char*

  • 保存了c_str()的返回值而沒有考慮string對象的生命周期

void append(int index, string arg)
{
printf("[append]arg.data()=0x%08p.
", arg.data());
m_args[index] = (char *)arg.c_str();
// m_args[index] = (char *)arg;
}

c_str函數的返回值的生命周期是和string對象的生命周期綁死的,所以上面這個函數結束之後arg析構,c_str的返回值就失效了,再用就是UB。這個函數還把他保存了起來,而且用的是char*不是const char*,觸發了兩條UB

  • printf輸出指針用錯了格式字元串

64位環境下指針長度是64bit,你把他當成unsigned int輸出,等著炸吧

總結:這段代碼並沒有任何意思,只暴露了編寫者C++基礎很弱


第一,這一點都不有趣。這段代碼問題實在太多了。

第二,地址一樣有什麼奇怪的。運行到rm-&>append(1, (string)"l2");的時候,前面一行的string已經被析構了。這是個C++基本常識。

第三,什麼叫「導致了賦值的問題」。你用了pass-by-value,編譯器按照你的吩咐做事情的。


想看內容還得跳轉,跳轉了居然還不使用代碼格式寫的代碼,然後居然還沒有縮進,然後這個代碼哪裡有意思了??還「見仁見智」地說說。。。題主你是故意使用激將法的吧。。

為了怕有無聊的人說我沒答題,那麼我答題如下:我不能,回答完畢。


因為前面 append 參數中的 string 對象已經析構掉了,但還用著它的.data(),當然會出問題。

另外,使用 printf 輸出指針應該使用 %p 而不是 %x。


零分,下一個


就這垃圾代碼,看了一眼頭引用就關了,然後忍住沒吐又回去看了,寫了個(string)"xxx",這次是真的關了。

智力障礙tag好評。


其實這個問題從一個側面證明Linus當初黑C++是有道理的,C++的確是「糟糕程序員的垃圾語言」

此題目的代碼就是最好的詮釋!如果寫這個的人做項目,不敢想,必然是一場災難。


這技炫的,我根本看不懂…

但是看最後一段說的,我彷彿又看到了計算機二級的題:

a = 1;

b = 1;

c = a+++++b;

c = ?


不能,下一題


你是騙熱度的吧?這種東西是個程序員都不會這麼寫,除了計算機等級考試命題題庫的那幾個老頭子喜歡這麼玩來炫技。語法玩的好有毛用。


一段令人窒息的代碼


硬是把面向對象寫成面向過程

慢慢更新……

少用指針,少用c寫c++

1.第一次見main函數結尾寫 return 1的

2.class裡面全是public,直接寫結構不是更方便嗎,還有把m_args直接公開了真的好?

3.c++裡面用printf,有好好的std::cout不用

4.構造函數直接賦值m_args會更好,m_args用string會更好,或者用容器


值傳遞,後面的append,前面的就析構了。。然後想幹嘛,完全不知道想表達什麼。。。

這就是不好好聽課,瞎裝,看吧,車禍了吧,主要我不知道他想幹嘛。。而且也不有趣,這不就是瞎?寫出來的嗎。


看到char就知道這是是一段垃圾


你確定這是c++而不是c?


這是當年看了什麼書才能寫出這樣的代碼的...


垃圾。

鑒定完畢。


我看到同時混用C和C++頭文件就直接關掉了

stdio.h

iostream

string

string.h

人才啊,好歹也要用cstdio和cstring吧


1,頭文件很奇怪

2,違反資源使用原則,管殺不管埋

3,使用printf沒注意32和64位區別

4,直接使用指針是很危險的,特別是跳出函數,string就析構了。如果只是列印沒關係,千萬別干別的。

5,地址一樣是個意外吧,未定義行為,不能假設編譯器會這麼搞。

6,因為append一樣,所以setargs一樣。

總體來說,考的基礎知識很簡單,代碼寫的太爛了。


C++析構函數在什麼情況下會被系統調用

雖然我寫Java的...但是這個問題我也是知道答案的


好大一坨翔


函數是值傳遞而不是引用傳遞,當string對象拷貝給函數的形參,實參就被析構了,而且,拷貝string對象是非常不明智的做法,總之,這代碼很爛


推薦閱讀:

既然c++的非virtual的函數可以重定義,virtual函數相比非virtual的有什麼優勢?
用MFC做的貪吃蛇遊戲,求大神。?
C++ primer 第四版這段關於vector的程序是否有未定義的行為?
c/c++中簡單加法出現奇怪的錯誤?
如何使用C++11實現跨平台的定時器timer?

TAG:CC |