gamer-project/gamer

Potential danger for using `convertToString().c_str()` in `Par_EquilibriumIC.cpp`

Opened this issue · 0 comments

Problem Description

  • Unable to get the correct content for the char array returned by the combining usage of the defined function convertToString() along with the C++ c_str() function. For the code snippet below, one will find the value for c is empty, instead of the expected value params.ExtPot_Table_Name.
    const char * c = convertToString(params.ExtPot_Table_Name).c_str();
    fstream file;
    file.open(c, ios::in);  # does not work
  • Possible Explanation: If one use convertToString(...).c_str() without saving the intermediate product convertToString(...), the object thus returned probably by convertToString(...) get freed immediately (probably because it is not referred any longer, see here), causing the value of the pointer returned by c_str() becomes empty, since the original string object is freed and does not exist anymore (also see 3rd bullet point in Note).

    Notes

    • convertToString() returns a string object
    • c_str() returns a const char* pointer to an array that contains a null-terminated sequence of characters (i.e., a C-string) representing the current value of the string object (the object returned by convertToString() in this case)
    • The value of the pointer returned by s.c_str() will be changed if we simply overwrite the current value of the string object s, even without touching the value of the pointer; see example code here

Workable Solutions

  • use strcpy to copy the value (original solution)
    char c[MAX_STRING];
    strcpy( c, convertToString(params.ExtPot_Table_Name).c_str() );
    fstream file;
    file.open(c, ios::in);
  • store the returned object by declaring a string object
    string s       = convertToString(params.ExtPot_Table_Name);
    const char * c = s.c_str();
    fstream file;
    file.open(c, ios::in);
  • passing the C-String directly to a const char * pointer, even without using the convertToString()
    const char * c = params.ExtPot_Table_Name;
    fstream file;
    file.open(c, ios::in);