0

The Current Issue

The value of a const char* seems to be changing to a nonsensical value.

Faulty Code Example

The intention of the code below is to create a string with the value of basedir. This process should keep the value of basedir constant; however, it inexplicably changes.

ProcessInfo get_process(int pid, const char* basedir) {
 cout<<basedir<<endl; 
 string basedir_str=basedir;
 cout<<basedir<<endl; 
 ....}

Current Output

./proc/16224/task
▒▒v▒=+

What could be wrong with the const char* to string assignment?

How Basedir Is Set

The variable basedir is being allocated with a call to the "parent" function get_all_processes.

Parent Function

vector<ProcessInfo> get_all_processes(const char* basedir) {
 DIR* dir;
 struct dirent *entry;
 vector<ProcessInfo> totalProcesses;
 //check to see if basedir can be opened
 if((dir =opendir(basedir))!=NULL){

    while((entry = readdir(dir)) != NULL ){
        int pid = atoi (entry->d_name);
        if(pid <=0){
            continue;
        }
        else{

        ProcessInfo currentProcess = get_process(pid, basedir); //<--call to get_process

        totalProcesses.push_back(currentProcess);
        }
    }
    closedir(dir);
}


return totalProcesses;
}

Call to Parent Function

myProcessInfo.threads=get_all_processes(threadList_fileName);
//threadList_filename='./proc/[pid]/task', in this case pid =16224

Solution

Eliminating the temporary const char* threadList_fileName and changing the arguments of the get_all_processes function. myProcessInfo.threads=get_all_processes(("./proc/"+pid_str+"/task").c_str());

Zephyr
  • 27
  • 1
  • 5
  • 1
    Can this be due to the string bet not NULL-terminated? The reference says it results in undefined behavior. – iksemyonov Feb 28 '16 at 00:10

1 Answers1

4

It looks like the variable "basedir" already points to memory you do not own anymore. Just by coincidence it still holds the value that you assigned to it. By allocating memory for the string "basedir_str" this memory is reused and overwritten by other data. So your problem lies outside the of the function "get_process".

How do you allocate "basedir"?

cwschmidt
  • 1,194
  • 11
  • 17
  • Thanks for the answer, @cwschmidt. _basedir_ is set when a call to the parent function is made. Its value is `("./proc/"+pid_str+"/task").c_str()`. I have already verified that pid_str is correct with _cout_ statements. – Zephyr Feb 28 '16 at 00:39
  • 2
    @Zephyr if `pid_str` is a `std::string` then the result of `c_str()` is only valid up until the next `;`. The memory it pointed to will be deallocated after that – M.M Feb 28 '16 at 00:42
  • @M.M Thanks so much! I deleted the assignment `const char* threadList_fileName=("./proc/"+pid_str+"/task").c_str();` and called the parent function with the immediate results of c_str(). The following solved it: `myProcessInfo.threads=get_all_processes(("./proc/"+pid_str+"/task").c_str());` – Zephyr Feb 28 '16 at 00:56