views:

111

answers:

4

Assuming I have a piece of code similar to this:

SOMESTRUCTURE *info;
info = malloc(sizeof(SOMESTRUCTURE));

while(something...)
{
     info->mini[0] = malloc(sizeof(SOMESTRUCTURE *)); // It's a structure inside the same structure
     while(something...)
     {
           info->mini[x]->name = malloc(sizeof(char *)*strlen(name));
           printf("%s\n", info->mini[0]->name); // This prints out the correct value
     }
}

printf("%s\n", info->mini[0]->name); // But now the value is lost and is null

How can I make the info->mini[0]->name value apply throughout the entire function?

+1  A: 

make sure x is never 0

stijn
+2  A: 

No, that should still be available to you. The only way you could lose the value would be if x were 0 on one of the iterations of your while loop or if you execute the malloc inside the outer loop without entering the inner loop - it's hard to tell if this is possible since you don't specify what something is in both cases.

It's true that variable created within a certain scope will disappear when you exit that scope but that isn't the case here. Allocated memory will survive scope changes. A given pointer to that memory may not but your pointer in this case (info is still in scope when you exit the outer while statement).

I do see one other potential problem - your malloc(sizeof(char *) * strlen(name)) should probably be malloc(strlen(name) + 1) (since sizeof(char) is always 1). It probably works because a char * will normally be bigger than a char but it's the wrong way to do it nonetheless.

However, I cannot see anywhere in your code where you actually set info->mini[0]->name to anything so I'm at a loss as to how it can ever have a correct value, unless it's somehow picking up a value from a previous malloc (this is possible since malloc itself is not required to clear the memory it gives to you).

You should post your actual code or preferably the smallest piece of code that exhibits the problem.

paxdiablo
slashmais
Just using `malloc(strlen(name) + 1)` is the only reasonable idiom I know for a dynamic allocation of a string...
Jens Gustedt
Good point @Jens, I really should know better by now :-)
paxdiablo
A: 

I see that you allocate info->mini[x]->name, and on the very next line, print it out.

In between, you don't seem to actually put any data into ->name, so I don't see how it can possibly print the correct value out.

Your allocation of ->name depends on the value of x at that time. But you never show us x being declared, or its value being set.

Please show us information about the declaration and assignments of x and where data is actually copied into ->name.

abelenky
+1  A: 

I recommend you to use glib's g_strdup function, see API - You'll find in glib many useful functions to handle strings :

So in your case to duplicate the string name you'd just do ...

info->mini[x]->name = g_strdup(name);

Edited As commented ... you can use standard strdup to get the same functionality:

info->mini[x]->name = strdup(name);

End Edition

By doing this, info->mini[x]->name will point to a dynamic allocated memory space that will be available outside your function - unless you free it.

If you don't want to use glib then:

info->mini[x]->name = malloc(sizeof(char) * (strlen(name) + 1));
strcpy(info->mini[x]->name,name);

In this case mind that the malloc is of sizeof(char) because a string is an array of chars not of char *, as you had before. +1 is to save last char for null terminated char.

msalvadores
Or, since a huge number of C implementations _have_ `strdup()`, use it instead. Or, if your implementation doesn't, just write one (http://stackoverflow.com/questions/252782/strdup-what-does-it-do-in-c/252802#252802) and not bother about trying to incorporate `glib`. There's many good reasons to use glib, a piddling little thing like strdup isn't one of them :-)
paxdiablo
sure @paxdiablo, my point was that there are many useful functions in glib to handle strings. But, I do agree with you, there're many other functionalities in glib that makes it a very useful lib. Answer edited to make the point that using just plain strdup is also a good option. And +1 to your comments. Cheers.
msalvadores