简体   繁体   中英

Array of const char*

I'm writing a C++ program that uses the RRD libraries that require an array of 'const char*' for their functions. I thought I could just declare the array, and then initialize each element of the array, but changing one, changes all of them. Obviously I'm missing something. Here's an example similar to the code I am writing (ie it exhibits the same problem).

string intToString(long i)
{
    stringstream ss;
    string s;
    ss << i;
    s = ss.str();
    return s;
}

int main(){
        const char* av[5];
        int i = 0;
        int j = 0;
        for(i=0;i<5;i++){
                j= 0;
                av[i] = intToString(i).c_str();
                for(j=0;j<5;j++){ cout << j << " : " << av[j] << endl;}
        }   

}

Any help would be appreciated.

The const char* returned by the c_str() method of a std::string points to a buffer owned by the std::string and only remains valid until the next call to a mutating method of the std::string . If you want to retain the contents of this buffer, you need to copy its contents somewhere else.

Edit: Alternatively, you could retain an array of std::string to manage the storage of the strings and temporarily store the c_str() pointers in a parallel array of const char* as required for the interface. This obviates the need to copy the strings or manually deallocate the copies. In any case, it's important to not change any std::string while you are holding the const char* value returned by a prior call to c_str() .

string::c_str returns temporary pointer. You could use strdup to get persistent pointer.

// don't forget to release memory later
av[i] = strdup( intToString(i).c_str(); ); 

Or you could allocate all buffers manually and then use string::copy to copy string data.

Bringing everything together, you can write your program like this:

#include <sstream>
#include <iostream>

std::string intToString(long i)
{
    std::stringstream ss;
    std::string s;
    ss << i;
    s = ss.str();
    return s;
}

int main(){
    const char* av[5];   // declared but not initialised
    std::string sav[5];  // std::string has a ctor, so they're initialised
    for(int i=0;i<5;i++){
        av[i]="";    // initialise each const char*
    }

    for(int i=0;i<5;i++){
        sav[i] = intToString(i);  // Keep the original in sav[]
        av[i] = sav[i].c_str();   // point to each string's contents
        for(int j=0;j<5;j++){ std::cout << j << " : " << av[j] << std::endl;}
    }   

}

@Philip: Note that your program prints every av[] after each av[] is re-initialised.

Note that memory management is handled by sav[]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM