-3

I'm using the following function to return the current amount of memory installed:

const char* Aries::Memory::GetInstalledMemory() {
    MEMORYSTATUSEX statex;
    statex.dwLength = sizeof(statex);
    GlobalMemoryStatusEx(&statex);
    std::stringstream ss;
    ss << statex.ullTotalPhys / (1024 * 1024 * 1024);
    return ss.str().c_str();
}

I am using it in conjunction of another stringstream and output it to the screen:

CryLogAlways("$1[Aries | System]$2 Probe system.");
Aries::Memory *pMem = new Aries::Memory();
stringstream ss;
ss << "$1[Aries | System]$2 Result of probe: installed memory is ";
ss << pMem->GetInstalledMemory();
ss << "GB.";

The expected output is:

$1[Aries | System]$2 Result of probe: installed memory is 32.00GB.

The output I get is:

Ö

Meanwhile if I tweak the function so that it returns a DOUBLE, it works fine:

DOUBLE Aries::Memory::GetInstalledMemory() {
    MEMORYSTATUSEX statex;
    statex.dwLength = sizeof(statex);
    GlobalMemoryStatusEx(&statex);
    return statex.ullTotalPhys / (1024 * 1024 * 1024);
}

It seems that some error with casting using ostringstream inside the GetInstalledMemory() function is causing this. However I need to return a const char *.

The output of GetInstalledMemory seems to be corrupting the entire stringstream where it is used; where is this going wrong, and how can I fix it?

AStopher
  • 4,207
  • 11
  • 50
  • 75

1 Answers1

3

ss.str() returns a std::string object, but in your code it will only exist as a temporary during that one line of code. Then you call c_str() which gives a pointer to the memory which that temporary string owns. But as soon as your function returns that memory becomes invalid to access since the temporary was destroyed.

A good solution is to change GetInstalledMemory to return a std::string object instead of a character pointer. Then it can just return ss.str(); and the string objects will take care of everything.

TheUndeadFish
  • 8,058
  • 1
  • 23
  • 17
  • A nice explanation, cheers (I plan to accept yours as it is the better answer, although Ed Heal answered first)! I never thought of it that way but it makes perfect sense. – AStopher Jan 14 '17 at 15:56