0

I'm creating a function for get the directory from the current exe file, when I use the variable inside the function ExePath, I get the correct directory, but if I use the return value from the function ExePath in another function, I get Japanese characters. This is my code:

#include <Windows.h>
#include <iostream>
#include <string>
#include <wchar.h>

using namespace std;

LPCWSTR ExePath();

int _tmain(int argc, _TCHAR* argv[])
{
    // ------ > HERE SHOWS JAPANESE CHARACTERS < -------------------------
    MessageBox(NULL, ExePath(), L"Inside main function", MB_OK); // Here show foreign characters

    return 0;
}

// This function returns the directory of this current exe file
LPCWSTR ExePath()
{
    // Get Exe Path
    WCHAR* buffer = new WCHAR[MAX_PATH];
    DWORD len = GetModuleFileName(GetModuleHandle(NULL), buffer, MAX_PATH );
    buffer[len] = L'\0';
    // Get only the directory (without the file name)
    wstring ws(buffer);
    const size_t last_slash_idx = ws.rfind('\\');
    if (std::string::npos != last_slash_idx)
    {
        ws = ws.substr(0, last_slash_idx);
    }
    // Show the directory
    // ws.c_str() = directory
    // ------ > HERE SHOW THE CORRECT DIRECTORY < ------------------------
    MessageBox(NULL, ws.c_str(), L"Inside ExePath Function", MB_OK); // Here show the correct directory
    return ws.c_str();
}

What am I doing wrong?

logic
  • 1,739
  • 3
  • 16
  • 22
FelipeDurar
  • 1,163
  • 9
  • 15
  • @MattMcNabb _... `ws.c_str()` points dynamically allocated memory ..._ that gets deleted as soon `ws` goes out of scope. So what? Oh, wait. I've got your point. I'm reopening the question, hopefully you have a better dupe or answer at hand. – πάντα ῥεῖ Mar 26 '15 at 23:19
  • 1
    @FelipeDurar make it `wstring ExePath()` and put `ExePath().c_str()` in your MessageBox call. As explained in the linked duplicate, you cannot use the result of `c_str()` after the string it referred to has gone out of scope. – M.M Mar 26 '15 at 23:32
  • Also there is a memory leak , `buffer` is never `delete[]`'d. The line `wstring ws(buffer)` makes a new string with its own internal buffer whose contents are copied from `buffer`. It's not possible to have a string wrap an existing buffer. – M.M Mar 26 '15 at 23:33
  • 1
    While you are changing `ExeName()`, there are several other optimizations you can make to it: 1) use `WCHAR buffer[MAX_PATH+1];` instead of `WCHAR* buffer = new WCHAR[MAX_PATH];`, 2) use `NULL` instead of `GetModuleHandle(NULL)`, 3) use `wstring ws(buffer, len);` instead of `wstring ws(buffer);`, 4) use `ws.erase(last_slash_idx);` instead of `ws = ws.substr(0, last_slash_idx);`, and 5) of course, use `return ws;` instead of `return ws.c_str()`. – Remy Lebeau Mar 26 '15 at 23:37

0 Answers0