Good time of day. There is a class, he has a member

const char **_files_container; 

If I understand correctly, this is an array of "C strings". In the constructor, I initialize this array

 this->_files_container = new const char*[10]; 

Thus, I can put 10 const char [] in it;

Next, I use the library boost :: filesystem, browsing through the folder and the found files just want to be _files_container into this very _files_container as text

Here I encounter a problem:

 itr->path().string(); 

Returns the string, as it should, but of type string , but I need it turns out const char*;

Well, I can transform such differences with c_str() :

 this->_files_container[0] = itr->path().string().c_str(); 

And here is the gag. I deduced in the console cout << this->_files_container[0] << endl; and get .. just some graphical artifacts of some kind, either empty or just the letter e .

If you fill the array with your hands, for example:

 this->_files_container[0] = "Fire in the hole!"; 

That all works as it should.

What am I missing or do not know, tell me what the problem is?

    3 answers 3

    Correct solution

    Instead of const char **_files_container; create std::vector<std::string> _files_container and do not suffer.

    Masochistic solution

    Manually manage memory and copy strings to char[]

     std:: string path=itr->path().string(); this->_files_container[0] = new char [path.size()+1]; strcpy( this->_files_container[0], itr->path().string().c_str()); 

    In this case, among other things, you need to remember to remove the memory yourself when it is no longer needed.

    Why it happens

    The string returned from tr->path().string() is temporary objects and is deleted upon completion of the statement. accordingly, when later someone tries to apply for a pointer to this memory, garbage is already contained there.

    • Thanks for the two solutions. The goal is to write a prog precisely according to the precepts of the “old school”, so I used the masochistic solution. It came with one caveat - I am writing in MS VS, and the studio always swears at strcpy, offering to use either strcpy_s or the _CRT_SECURE_NO_WARNINGS flag. strcpy_s did not want to copy by throwing exceptions and referring something to the template, with the flag working as it should. What would you recommend? They write that strcpy_s is a pure MS chip, and strcpy is a classic. On Linux strcpy_s does not take off, I understand? - Leo
    • lol, using boost 'a is no longer an oldscool, but oh well ... About strcpy_s , in fact - purely MS'ovskaya ... although now it’s pushed as an optional extension of the standard C11, but as far as I know not a single libc in the * nix world supports it ... My opinion - almost all *_s versions are counterproductive, and those that make sense have POSIX counterparts. Yes, for the proper use of strcpy the responsibility lies with the programmer ... - Fat-Zer

    Calling path().string() may return a temporary string, respectively, after the execution of this expression, it will be destroyed, and the saved pointer will become invalid. Save the returned lines in the vector:

     ::std::vector<::std::string> _files_container; _files_container.emplace_back(itr->path().string()); 

      Judging by itr->path().string() , you loop around the directory and the iterators die on each iteration, and the pointers to their data hang. Trying to then read the data from the broken pointer, you get a random output.

      You need to copy the strings to yourself in _files_container .