0

I have a strange issue. I allocate char[] values in struct array, but they get lost: ------- The struct is this one :

typedef struct _Settings
{
    const char* str;
    uint val;
}Settings;

------- I create it like this :

int nn=10;
settings = new Settings[nn];
for (int i = 0; i < nn; i++) {
        string strr = "thisOneIs";
        strr.append(std::to_string(i));
        settings[i].str = strr.c_str();
        string teststr = settings[i].str;   //// (1)
        settings[i].val = i + 1;
}

..... at (1), I get the correct values.

But if I then call this (same place, right after the code above), the settings[i].str is empty:

for (int i = 0; i < nn; i++) {
        string teststr = settings[i].str;       ///// (2)
        std::cout << settings[i].str << "=" << settings[i].val << "\n";
    }

... at (2), I get empty.

Does anyone have a clue why? Thanks!

Steve
  • 3
  • 3
  • 1
    strr is a local variable with the automatic storage duration. Its scope is the block code of the for loop. After exiting the loop the variable is not alive any more and the corresponding pointer is invalid. – Vlad from Moscow Dec 25 '17 at 20:22
  • 1
    `const char* str` is a pointer, which you point it to the temporary object that gets destroyed at the scope end, what do you expect? – Killzone Kid Dec 25 '17 at 20:22
  • You're right. But how can I copy the string value from strr into settings[i].str permanently ? – Steve Dec 25 '17 at 20:29
  • @Steve: A [recommended read](https://stackoverflow.com/questions/46991224/are-there-any-valid-use-cases-to-use-new-and-delete-raw-pointers-or-c-style-arr). – user0042 Dec 25 '17 at 20:43

1 Answers1

2

The line at (1) is a problem because you are storing a pointer to some memory that is not valid when the loop ends.

string strr = "thisOneIs";      // A temporary object in the loop.
strr.append(std::to_string(i));
settings[i].str = strr.c_str(); // Pointer that won't be valid when the loop ends.

If you learning about low level language features, it's ok to experiment with using char* and raw memory. If you are trying to get a working program, just use std::string.

Also simplify the definition of Settings. You don't need all the typedef non-sense in C++.

struct Settings
{
    std::string str;
    uint val;
};
R Sahu
  • 204,454
  • 14
  • 159
  • 270
  • Thanks! Unfortunately i must use this typedef for Settings -- it is for interfacing with legacy software (calling .dll functions using this sort of stuff). How could I copy the string value from strr into settings[i].str permanently, instead of pointer only? – Steve Dec 25 '17 at 20:28
  • @Steve, you have to make a copy that string. Lookup `strdup` on the net. – R Sahu Dec 25 '17 at 20:31
  • char * strdup(const char *str1); duplicates str1. But in my case, I have a string : strr. Whatever is in this string must be placed into const char* str within the struct: settings[i].str ... so the question is: how to copy a string into const char* ? Sorry if I misunderstood.. – Steve Dec 25 '17 at 20:40
  • Use `settings[i].str = strdup(strr.c_str());` – R Sahu Dec 25 '17 at 20:41
  • Nice! This is the solution. Thanks a lot! – Steve Dec 25 '17 at 20:43
  • But if you use `strdup` you might have memory leaks or you need some way to know when you should free the memory and when you should not. – Phil1970 Dec 25 '17 at 23:41