torvaJJ torvaJJ - 1 year ago 138
C Question

Split a string into double pointer in C

i am trying to convert a string (example: "hey there mister") into a double pointer that's pointing to every word in the sentence.
so: split_string->|pointer1|pointer2|pointer3| where pointer1->"hey", pointer2->"there" and pointer3->"mister".

char **split(char *s) {
char **nystreng = malloc(strlen(s));
char str[strlen(s)];
int i;

for(i = 0; i < strlen(s); i++){
str[i] = s[i];

char *temp;
temp = strtok(str, " ");

int teller = 0;
while(temp != NULL){
printf("%s\n", temp);
nystreng[teller] = temp;
temp = strtok(NULL, " ");
nystreng[teller++] = NULL;


return nystreng;

My question is, why isnt this working?

Answer Source

Your code has multiple problems. Among them:

  • char **nystreng = malloc(strlen(s)); is just wrong. The amount of space you need is the size of a char * times the number pieces into which the string will be split plus one (for the NULL pointer terminator).

  • You fill *nystreng with pointers obtained from strtok() operating on local array str. Those pointers are valid only for the lifetime of str, which ends when the function returns.

  • You do not allocate space for a string terminator in str, and you do not write one, yet you pass it to strtok() as if it were a terminated string.

  • You do not increment teller inside your tokenization loop, so each token pointer overwrites the previous one.

You have an essential problem here in that you do not know before splitting the string how many pieces there will be. You could nevertheless get an upper bound on that by counting the number of delimiter characters and adding 1. You could then allocate space for that many char pointers plus one. Alternatively, you could build a linked list to handle the pieces as you tokenize, then allocate the result array only after you know how many pieces there are.

As for str, if you want to return pointers into it, as apparently you do, then it needs to be dynamically allocated, too. If your platform provides strdup() then you could just use

char *str = strdup(s);

Otherwise, you'll need to check the length, allocate enough space with malloc() (including space for the terminator), and copy the input string into the allocated space, presumably with strcpy(). Normally you would want to free the string afterward, but you must not do that if you are returning pointers into that space.

On the other hand, you might consider returning an array of strings that can be individually freed. For that, you must allocate each substring individually (strdup() would again be your friend if you have it), and in that event you would want to free the working space (or allow it to be cleaned up automatically if you use a VLA).

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download