2014-03-04 46 views
1

我在Visual Studio 2013上編寫C++ dll。我的dll應該從ini文件讀取參數。所以,我爲此創建了一個函數(ReadConnectionSettings())。在函數工作期間,我的靜態變量serverIP正確地獲取了值,但是一旦完成運行變量(serverIP)的函數失去了它的值。什麼似乎是問題?靜態LPTSTR變量在函數執行後丟失數值

static LPTSTR serverIP = _TEXT(""); 

void ReadConnectionSettings() 
{ 
    TCHAR url[256]; 

    GetPrivateProfileString(_T("Connection"), _T("Url"), _T(""), url, 256, NameOfIniFile); 

    serverIP = url; 

} 
+0

'url'被分配到堆棧上,並在方法結束時隨後被吹走。如果您需要更多的永久存儲空間,則需要更長久的存儲位置。 – dlev

+2

'url'是一個本地分配的變量,因此它在ReadConnectionSettings返回後釋放,因此serverIP指向釋放內存。嘗試:'serverIP = _tcsdup(url);'祝你好運,當你完成它時,不要忘記釋放你的記憶! –

回答

5

您在堆棧存儲器url指向指針serverIP

當函數退出時,這將超出範圍,因此指針指向垃圾。

你可以做的是讓serverIP代替一個緩衝區,而複製到它的URL中。然後它會持續下去。

即:

static TCHAR serverIP[256] = _TEXT(""); 

然後:

_tcsnccpy(serverIP, url, 255); 

或者作爲@DavidOtano建議,你可以保留現有的服務器IP指針,與用途:

serverIP = _tcsdup(url); 

但是,如果你做到這一點,你動態地分配內存,所以需要記得打電話:

free(serverIP); 

當你不再需要它時,避免內存泄漏。

+1

因爲這是C++,所以可以簡單地使用'std :: wstring'而不是原始字符緩衝區:'std :: wstring'自動處理內存分配和釋放,避免那些討厭的內存泄漏和雙重刪除Undefined行爲和whatnot。但是,全局變量是Evil(TM)。因此,不是使用'std :: wstring'全局變量,而是從函數返回一個'std :: wstring'。 –

+0

@ Cheersandhth.-Alf:好的一點,+1的答案。問題標籤說'C++',但我看到的代碼看起來更像是支持unicode的C,所以我相應地回答了!當然,你的答案在C++世界中更好。 – Baldrick

3

您將靜態指針變量設置爲指向函數返回後不再存在的局部變量。

從Windows程序中的函數返回字符串的一種好方法是返回std::wstring

試試看。


關於LPTSTR_TEXT,只有當您打算支持MFC在Windows 9x中的DLL需要這個。是這樣嗎?如果沒有,只是溝通微軟的愚蠢。


根據上述建議(即興,通過編譯器的手觸及)固定代碼:這段代碼的

auto connection_settings() 
    -> std::wstring 
{ 
    std::wstring url(256, L'#'); 

    auto const n = GetPrivateProfileString(L"Connection", L"Url", L"", &url[0], url.size(), NameOfIniFile); 
    url.resize(n); 
    return url; 
} 

一個很好的特性是它不再修改了全局變量