vc 6 0標準庫string類的bug

2021-04-16 07:34:27 字數 1504 閱讀 2484

許式偉2006-12-23

basic_string並不象它的名字那樣,只可能是乙個字串。有時候,它不那麼象字串。例如:

typedef std::basic_string

<

double

>

doublearray;

此時,basic_string是乙個double型別的動態陣列。你可能說,為什麼不用vector呢?如下:

typedef std::vector

<

double

>

doublearray;

這兩者有什麼不同?其實最大的不同,在於basic_string類通常是基於copy-on-write技術的。這意味著basic_string的賦值操作(operator=)只是乙個簡單的加引用計數(addref),是相當快速的。而vector類的賦值操作則是真正的記憶體拷貝過程。

現在我要實現乙個矩陣(matrix)類。你可以想象一下現在要矩陣的各種運算,例如加法(operator+):

matrix 

operator+(

const

matrix

&a, 

const

matrix&b)

你可以發現,如果matrix內部採用vector,而不是用basic_string,那麼matrix類的operator+中就有多次無謂的記憶體拷貝過程。 

我的matrix類一直工作的很好,直到有一天,我發現某個matrix的資料少了。跟蹤發現,問題出在basic_string的copy-on-write實現上。vc++ 6.0的stl中,basic_string通過_split函式進行**:

class

basic_string }};

問題出在上面的assign語句上。你的陣列被理解為是乙個'/0'結尾的「字串」。這樣_split操作完成後,如果某個陣列元素為0,資料變少了。

找到了肇事者,修改**還是很容易,如下: 

void

_split()

} //

@@code modify: assign(_temp); ---> bug fixed by xushiwei

問題在於: 

既然它是標準庫,直接修改它的**並不是很好,因為你的同事(或者其他人)還在用著有問題的版本。

如果你採用multithread dll模式鏈結c++標準庫,這意味著就算你修改了vc++的標頭檔案也沒用,因為編譯器最終鏈結的是dll中的**,而不是你修改後的**。

怎麼辦呢?

winx就這個問題進行了一定程度的修復(參見最新的發布包)。也就是說,只要你包含了最新的winx,多數情況下不會出現此bug。但如果你採用multithread dll模式鏈結c++標準庫(問題挺嚴重,因為這是推薦的鏈結方式),那麼你需要小心使用string、wstring類(但是其他類諸如basic_string

沒問題),因為此模式下winx並沒有修復該bug。注意不要讓字串中出現'/0'字元即可。如果確實需要出現'/0'的字串,可使用winx::cstring類。 

VC6 0迴圈的彙編

今天突然來了興趣,想看看彙編級的迴圈.include using namespace std int main 1 include 2 using namespace std 3 4 int main 5 00401290 jmp main 28h 00401278 11 12 00401292 p...

VC6 0存在的問題

問題1public cstring file add2 0 初始化為零後,在成員變數中消失,從而出錯 儲存路徑 cstring fileadd 儲存 iplimage first image null 初始化為零後,在成員變數中消失,從而出錯 iplimage first image 原因,在.h檔...

VC 6 0的簡單使用

學習重點 學習內容 工欲善其事,必先利其器,所以學習編譯器的使用很重要,windows環境下的編譯器比較多,vc 6.0就是其中比較經典的一款,接下來我們將學習其簡單使用 確定所用電腦已安裝vc 6.0 1.開啟vc6.0,一般桌面有其圖示,直接開啟就可以了,如果沒有,就單擊開始 2.開啟vc,出現...