2013-12-23 115 views
-1

製作Direct2D的程序,我想轉換從intWCHAR C++需要交代,所以我寫了下面的代碼上`靜態常量WCHAR *`

void DemoApp::OnRender() { 

//... 

int a = 256; 
std::wstring wStr = std::to_wstring(a); 
static const WCHAR* pStrNum = wStr.c_str(); 

//Print the number to the screen 
_pRenderTarget->DrawText(
    pStrNum, 
    sizeof(pStrNum)/sizeof(pStrNum[0]), 
    _pTextFormat, 
    rect, 
    _pBrush); 
//... 
}; 

然而,一個循環之後,pStrNum改變的東西奇怪的是,起始字符是5028十進制的基數。

搞亂一點後,我改變了轉換代碼,以

const WCHAR* pStrNum = wStr.c_str(); 

的字符串幾乎正確地打印在屏幕上和一切似乎是除了具有2的值sizeof(pStrNum)/sizeof(pStrNum[0])正常,因此只打印前兩個字符在屏幕上。畢竟,我必須使用lstrlenW()來獲取該字符串中元素的數量。

我需要爲什麼static const WCHAR*不同於const WCHAR*並導致交代錯誤

爲什麼sizeof()不會在這種情況下工作嗎?

回答

1

我認爲(我會知道,如果我得到很多downvotes的),你的代碼的行爲是未定義

這是因爲

static const WCHAR* pStrNum = wStr.c_str(); 

static存儲將被初始化一次。

但每次函數被調用時wStr都會被初始化,這就是問題所在:隨後對函數的所有調用中,指針都會懸空而行爲不確定。

如果我是你,我會在時間的基礎上評估.c_str()。這樣做不會有性能開銷。

要回答你的問題:使用wStr.size()獲取字符串的長度:sizeof()返回數據類型的大小(在編譯時計算),而不是字符串長度。

+1

我認爲這是未定義的一個不同的原因:它將被初始化爲保存一個指向在函數調用後死亡的局部變量的指針。由於它只被初始化一次,它爲下一次調用保留一個懸掛指針。 – juanchopanza

+1

這(最初的答案)是完全錯誤的。 @juanchopanza對此有一個正確的分析:因爲該變量是靜態的,所以只有在第一次調用該函數時才進行初始化。 (如果這是他的確切代碼,那麼使'wStr'靜態也可以解決這個問題,但是,那麼他可能會寫'static wchar_t const pStrNum [] = L「256」;'並且完成它。) –

+0

對了,我修改了。沒有注意到,該操作已經將代碼包裝在一個函數中。 – Bathsheba

1

sizeof(pStrNum)給你的大小WCHAR*,而不是它指向的字符串。

當您有權訪問數組聲明時,只能使用sizeof(arr)/sizeof(arr[0])來計算數組的長度。在其他時候,您需要傳遞一個大小以及數組,或遍歷其元素,直到找到標記元素結尾的標記元素。對於C風格的字符串,您可以迭代其元素,直到找到值爲\0的值。 wcslenwchar_t這麼做。

_pRenderTarget->DrawText(
    pStrNum, 
    wcslen(pStrNum), 
    _pTextFormat, 
    rect, 
    _pBrush); 

或者,簡單,因爲Kerrek SB建議,刪除所有使用pStrNum

_pRenderTarget->DrawText(
    wStr.data(), 
    wStr.size(), 
    _pTextFormat, 
    rect, 
    _pBrush); 
+2

爲什麼不簡單'DrawText(wStr.data(),wStr.size(),...)'? –

+0

@KerrekSB沒有任何理由比我慢。我現在在回答中已經注意到了這一點。 – simonc

0

sizeof給你什麼,你傳遞給它的對象表示的大小。您正在給予pStrNumsizeof,並且pStrNumconst WCHAR*,因此您得到的是指針的大小。 sizeof不能計算出字符串的長度。

0

您的代碼不起作用的原因是編譯器使用變量的靜態類型來評估sizeofsizeof(pStrNum)將是4或8個字節,取決於您的操作系統,因爲變量是一個指針。

只需重寫代碼:

_pRenderTarget->DrawText(
    wStr.c_str(), 
    wStr.length(), 
    _pTextFormat, 
    rect, 
    _pBrush); 

,你會沒事