开发者

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 use malloc(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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜