2011-06-09 64 views
0

我正在研究一些C++代碼,並在下面描述的函數中遇到一些問題。我之前並沒有使用過多的C++,至少不是很久以前,所以我在很大程度上嘗試學習。 win32api對混淆因素沒有多大幫助...使用'new'在C++中動態分配內存?

該函數被成功調用兩次,之後在應用程序中調用該函數時在稍後調用失敗時失敗。

PTSTR getDomainFromDN(PTSTR dnPtstr) { 

size_t nDn=wcslen(dnPtstr); 
size_t *pnNumCharConverted = new size_t; 

wchar_t *szTemp = new wchar_t[10];   // for debugging purposes 
_itow_s((int)nDn,szTemp,10,10);    // for debugging purposes 

AddToMessageLog(EVENTLOG_ERROR_TYPE,szTemp);  // for debugging purposes (displays an integer value before failing) 
AddToMessageLog(EVENTLOG_ERROR_TYPE,TEXT("Marker A")); // for debugging purposes 
char *dn = new char[nDn]; 
    // !!!!!!!!!!!! all goes wrong here, doesn't get to next line, nDn does have a value when it fails (61) 
AddToMessageLog(EVENTLOG_ERROR_TYPE,TEXT("Marker B")); // for debugging purposes 

wcstombs_s(pnNumCharConverted,dn,nDn+1,dnPtstr,nDn+1); 

...more code here... 

delete[] dn; 
delete pnNumCharConverted; 

return result 
} 

起初我認爲這是一個內存分配的問題或東西,因爲它失敗就行char *dn = new char[nDn];,表示爲「標記A」的最後一個標記。我用指針delete[]進一步無效。我知道nDn是一個值,因爲我用_itow_s打印出來的消息日誌進行調試。我也知道dnPtrstr是一個PTSTR。

我嘗試使用malloc以及free()在舊的C風格,但這並沒有改善的東西。

+0

一旦你開始擺弄這樣的指針,這很棘手 – 2011-06-09 05:19:11

+7

'size_t * pnNumCharConverted = new size_t;'哦我的。 – 2011-06-09 05:20:23

+3

你正在使用太多'new'。 – Nawaz 2011-06-09 05:23:21

回答

2

我嘗試過清理你的代碼。 C++的一大竅門是在可避免的情況下不能明確地使用內存管理。使用矢量而不是原始數組。字符串而不是char指針。

並且不要不必要地動態分配對象。把它們放在堆棧上,它們被自動釋放。

和其他語言一樣,初始化變量

PTSTR getDomainFromDN(PTSTR dnPtstr) { 
    std::wstring someUnknownString = dnPtstr; 

    size_t numCharConverted = 0; 

    std::wstring temp; // for debugging purposes 
    std::ostringstream sstr; 
    sstr << temp; 
    AddToMessageLog(EVENTLOG_ERROR_TYPE,sstr.str().c_str());  // for debugging purposes (displays an integer value before failing) 

    AddToMessageLog(EVENTLOG_ERROR_TYPE,TEXT("Marker A")); // for debugging purposes 
    std::vector<char> dn(someUnknownString.size()); 

    AddToMessageLog(EVENTLOG_ERROR_TYPE,TEXT("Marker B")); // for debugging purposes 

    wcstombs_s(&numCharConverted, &dn[0], dn.size(), someUnknownString.c_str(), dn.size()); 

    ...more code here... 

    return result 
} 

這可能沒有解決您的問題,但它已消除了大量的潛在錯誤。 鑑於我無法從您提供的代碼中重現您的問題,這真的是我能做的最好的。

現在,如果您能夠使用理智的名稱而不是dnPtstrdn,它可能實際上幾乎是可讀的。 ;)

+0

「和其他語言一樣,初始化變量。」每種語言最近都沒有開發出來?:) – GManNickG 2011-06-09 06:30:23

+1

@GMan回到我的日子,我們甚至沒有變數!我們只有登記冊,我們很高興有他們! – Kongress 2011-06-09 13:49:04

1

我覺得你的問題是這一行:

wcstombs_s(pnNumCharConverted,dn,nDn+1,dnPtstr,nDn+1);

,因爲你是在告訴wcstombs_s高達NDN + 1個字符複製到DN是僅長NDN字符。

嘗試改變行:

wcstombs_s(pnNumCharConverted,dn,nDn,dnPtstr,nDn);

或許更好,但:

wcstombs_s(pnNumCharConverted,dn,nDn,dnPtstr,_TRUNCATE);

林不知道你是怎麼調試這個或AddToMessageLog是如何實現的,但如果你只是檢查日誌以跟蹤代碼,並且AddToMessageLog正在緩衝日誌記錄,則可能在刷新緩衝區之前發生錯誤。

+0

是的,我認爲我這樣做是因爲我認爲它佔字符串末尾的空終止符。儘管代碼不會在那裏失效,但它在標記A和B之間失敗,指向一行'char * dn = new char [nDn];'。我把這個功能當作自己的小程序來使用,它似乎在那裏工作得很好。它在前兩次在這個應用程序中運行良好,然後在被調用時出錯。剛剛嘗試了你所說的,它不起作用,但無論如何感謝 – Grub 2011-06-09 05:56:32

+0

@ user723459你可能需要發佈生活在「...更多代碼在這裏......」的代碼,也可能有助於查看你在哪裏調用這個函數,以及創建dnPtstr的位置以及您對函數結果所做的操作。 – Vusak 2011-06-09 06:05:28

+0

@ user723459超出分配塊(通常)的末尾寫入不會導致程序立即失敗,但它經常會損壞空閒空間舞臺,這會在未來某個'new'或'delete'中導致問題。 – 2011-06-09 07:28:08

0

如果您確定「char * dn = new char [nDn];」失敗,TRY 「set_new_handler」 - >http://msdn.microsoft.com/en-us/library/5fath9te(VS.80).aspx

在一個側面說明,幾件事情:

  1. 非常第一操作 「爲size_t NDN = wcslen(dnPtstr);」並非100%正確。 假設dnPtstr爲unicode,您正在對dnPtstr執行wcslen。但是,情況並非如此,因爲根據是否定義了UNICODE,它可能是PWSTR或PSTR。所以,使用_tcslen()。如果你花一些時間來理解UNICODE,非UNICODE的東西,它會更好,因爲它們會在Windows C++開發中幫助你很多。
  2. 爲什麼你使用這麼多「新」,如果你只在這個函數中使用這些變量(我假設它)。 首選堆棧的局部變量unles你有一個明確的要求。
+0

我會研究這個,謝謝。有沒有人有任何關於一本好C++書的建議,這會讓我對所有這些都感興趣,因爲我覺得我需要得到一些基礎知識。 ta – Grub 2011-06-09 07:02:45

+0

我將如何重做行'char * dn = new char [nDn];'而不使用'new'? – Grub 2011-06-09 07:04:55

+0

char dn [MAX_SIZE] = {0}; //將MAX_SIZE定義爲可以容納Dn的東西。事實上,由於您使用WindowsAPI,最好使用TCHAR dn [MAX_SIZE] = {0}; – bayCoder 2011-06-09 07:12:04