Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to pass vector of string to foo(char const *const *const)?

Edit: After implementing James Hopkin' suggestion, I still get the warnings of "invalid name 'null'", which is much better than those weird characters. Then, I went back and read the library document again, and it turns out that for that particular function, it's argument should have one more element of non-NULL string than the size of aNames. That additional string has some other purpose. After adding one more string, the code runs fine. It's all my fault, and I am so sorry.

Original post:

Hi,

This is my first post so please be nice. I searched in this forum and googled but I still can not find the answer. This problem has bothered me for more than a day, so please give me some help. Thank you.

I need to pass a vector of string to a library function foo(char const *const *const). I can not pass the &Vec[0] since it's a pointer to a string. Therefore, I have an array and pass the c_str() to that array. The following is my code (aNames is the vector of string):

const char* aR[aNames.size()];

std::transform(aNames.begin(), aNames.end(), aR, 
                boost::bind(&std::string::c_str, _1));
foo(aR);

However, it seems it causes some undefined behavior:

If I run the above code, then the function foo throw some warnings about illegal characters ('èI' blablabla) in aR.

If I print aR before function foo like this:

std::copy(aR, aR+rowNames.size(), 
          std::ostream_iterator<const char*>(std::cout, "\n"));
foo(aR);

Then, everything is fine. My questions are:

  1. Does the conversion causes undefined behavior? If so, why?

  2. What is the correct way to pass vector of string to foo(char const *const *const)?

like image 876
EXP0 Avatar asked May 21 '10 15:05

EXP0


2 Answers

Since foo only takes a pointer, my wild guess is that it requires a NULL-terminated array. Allocate an extra element for aR and assign NULL to it.

My suggestion would be:

std::vector<const char*> c_strings;
c_strings.reserve(aNames.size() + 1);

std::transform(
    aNames.begin(), aNames.end(),
    std::back_inserter(c_strings), 
    boost::bind(&std::string::c_str, _1)
    );

c_strings.push_back(0);
foo(&c_strings[0]);
like image 179
James Hopkin Avatar answered Oct 03 '22 04:10

James Hopkin


Well it's seems right to me. c_str create a null terminated array of char that is constant until the next non-const string operation. You store the c_str pointers in a const char* array.

I'm no boost specialist so the problem might be there, but my guess is that your strings in the vector are in an encoding that is incompatible with the one expected in function foo.

Check your code from the encoding point of view.

my2c

like image 29
neuro Avatar answered Oct 03 '22 04:10

neuro