1

I'm writing C++ dll on Visual studio 2013. My dll should read parameters from ini file. So, I've created a function for this purpose (ReadConnectionSettings()). My static variable serverIP gets value properly during the function working, however once the function complete running the variable (serverIP) loses its value. What seems to be the problem?

static LPTSTR   serverIP = _TEXT("");

void ReadConnectionSettings()
{
    TCHAR url[256];

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

    serverIP = url;

}
Nurzhan Aitbayev
  • 797
  • 1
  • 10
  • 23
  • `url` is allocated on the stack and will subsequently be blown away when the method finishes. If you need more permanent storage, you need a more permanent storage location. – dlev Mar 04 '14 at 06:03
  • 2
    `url` is a locally allocated variable, so it is freed after ReadConnectionSettings returns, and so serverIP points to freed memory. Try:`serverIP = _tcsdup(url);` Good luck, and don't forget to free your memory when you're done with it! –  Mar 04 '14 at 06:03

2 Answers2

5

You are pointing the pointer serverIP at stack memory url.

This goes out of scope when the function exits, so your pointer is left pointing to junk.

What you could do is make serverIP a buffer instead, and copy the URL into it. Then it would persist.

That is:

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

Then:

 _tcsnccpy(serverIP, url, 255);

Or as @DavidOtano suggested, you could keep your existing serverIP pointer, and use:

 serverIP = _tcsdup(url);

But if you do this, you're dynamically allocating memory, so will need to remember to call:

 free(serverIP);

when you no longer need it, to avoid a memory leak.

Baldrick
  • 11,712
  • 2
  • 31
  • 35
  • 1
    Since this is C++, one can simply use a `std::wstring` instead of a raw character buffer: the `std::wstring` takes care of memory allocation and deallocation, automatically, avoiding those pesky memory leaks and double deletion Undefined Behavior and whatnot. However, global variables are Evil(TM). So instead of using a `std::wstring` global variable, *return* a `std::wstring` from the function. – Cheers and hth. - Alf Mar 04 '14 at 06:16
  • @Cheersandhth.-Alf: Good point, and +1 to your answer. The question tag said `C++`, but the code I saw looked a lot more like unicode-aware C, so I answered accordingly! Your answer is better in the C++ world for sure. – Baldrick Mar 04 '14 at 06:27
3

You're setting the static pointer variable to point at a local variable that does not exist anymore after the function has returned.

A good way to return a string from a function in a Windows program, is to return a std::wstring.

Try that.


Regarding LPTSTR and _TEXT, you only need this if you intend to support MFC in DLLs in Windows 9x. Is that the case? If not, just ditch that Microsoft silliness.


The code fixed according to above advice (off the cuff, untouched by compiler's hands):

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;
}

One nice property of this code is that it no longer modifies a global variable.

Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331