Ono
Ono

Reputation: 1357

build a vector of char*

I am trying to build a vector, and supposedly the each char* within the vector is different. Here is the code:

static char *StatsManager::_statsOption[4] = {"min", "max", "mean", "stddev"};

void BuildStatsNameList(long ChanIdx)
{   
    for (int m = 0; m < 4; m++)
    {
        std::string statsName(StatsManager::_statsOption[m]);

        for (int n = 0; n < 1; n++)
        {
            statsName += "_";
            statsName += std::to_string(ChanIdx);
            statsName += "_";
            statsName += std::to_string(n);
            //sprintf (statsName, "s%_%d_%d", StatsManager::_statsOption[m],ChanIdx, n);
            StatsManager::_statsNameList.push_back((char*)statsName.c_str());
        }
    }
}

However, I noticed the char* (statsName ) in the statsName will become the same eventually. For example after the loop, the StatsManager::_statsNameList becomes

stddev_1_0
stddev_1_0
stddev_1_0
stddev_1_0

......

instead, I want it as

min_1_0
max_1_0
mean_1_0
stddev_1_0

Anyone has any idea how to avoid the statsName getting overwritten again and again? Thanks.

Upvotes: 0

Views: 84

Answers (2)

4pie0
4pie0

Reputation: 29724

Behavior of your program is undefined because you are accessing pointers to memory allocated in BuildStatsNameList function that has been deallocated as soon as BuildStatsNameList returns to the caller.

void BuildStatsNameList(long ChanIdx)
{   
    for (int m = 0; m < 4; m++)
    {
        std::string statsName( ...option[m]);  // local variable
        _statsNameList.push_back( (char*)statsName.c_str()); // no problem so far
        }
    }
}

// but here _statsNameList holds pointers to invalid memory

Consider usage of std::vector< std::string> instead or use strdup which will copy the c-string for you to new location ( if you absolutely have to stick to char*).

Upvotes: 4

merlin2011
merlin2011

Reputation: 75565

If you want C-style strings that will persist, one option is to use strdup.

   StatsManager::_statsNameList.push_back(strdup(statsName.c_str()));

Note, however, that you will need to free the memory yourself after you are done with those strings.

Upvotes: 3

Related Questions