Better way to maintain an array of strings in C
Is there a better way to maintain a list of strings in C besides using typedef char* and declaring an array of type string? I am trying to manage a list of member names that join the group via socket program. But every time a new member joins the group - old member names get overridden. Part of the sample code is like this:
typedef char * string;
string List[10]开发者_如何学运维;
and new member joins like this:
List[index]=membername;
Thanks.
It all depends on how membername
is allocated. If it's a static string that you reuse, filling it with a new name every time one comes in, then you are overwriting the string multiple times. Storing the pointer to the string won't store the contents of the string, it will simply save its address.
To do this properly, you need to allocate (using malloc()
) a new string for each new name. Each new string pointer is then assigned to a different member in the array.
With basic C-types you will need to have the List as a pointer-to-a-pointer and then for every new membername realloc it for another string (or have it set to a constant maximum amount of strings -- which can cause nasty memory overruns -- but if you modulate the index its safe).
For every new membername you need to allocate a
char*
(c string) for this membername, if you only want to store this membername you can usemalloc(strlen(membername)+1)
to allocate it with space for the null terminated 0.When this is done you have memory to insert the string, do this by
strcpy(List[index++], membername)
.If you go for the static max amount of strings you have to use
strpcy(List[(index++)%ALLOCATEDSTRINGS,membername)
.
You're probably (not enough context) not allocating the strings properly.
string List[10];
only allocates an array of 10 string
, i.e. 10 char *
, i.e. 10 character pointers. It doesn't allocate any storage for the strings themselves.
So if your membername
above is e.g. a global char *
that you're copying data from the network to, all your slots in List
will end up pointing to that very same memory location.
To make it work, you'd need to allocate (and carefully free) all the slots in List
. Something like:
List[index] = strdup(membername);
For better chances of catching errors early, initially set your List
to all null pointers.
for (int i=0; i<10; i++) List[i] = NULL;
and when a user "goes away", free and reset that slot to NULL:
free(List[index]);
List[index] = NULL;
That way you'll get nice, nasty segfaults if you don't manage your slots carefully enough :-)
I'd use an array of allocated char*, and if you need to, make it so you can dynamically grow the array.
So you'd have:
char **List = calloc(num_members,sizeof(char *));
Then when someone joins the group you'd have:
List[current_index] = calloc(strlen(new_user_name) + 1,sizeof(char));
strcpy(List[current_index++],new_user_name);
Keep in mind then that num_members
would need to start big enough to handle as many members as may want to join, or you'd have to occasionally reallocate a bigger array.
精彩评论