0

I'm a C noob and I'm having problems with the following code:

#include <stdio.h>
#include <string.h>
#include <unistd.h>

void split_string(char *conf, char *host_ip[]){

    long unsigned int conf_len = sizeof(conf);
    char line[50];
    strcpy(line, conf);

    int i = 0;

    char* token; 
    char* rest = line; 

    while ((token = strtok_r(rest, "_", &rest))){
        host_ip[i] = token;
        printf("-----------\n");
        printf("token: %s\n", token);
        i=i+1;
    }
}

int main(){ 

    char *my_conf[1];

    my_conf[0] = "conf01_192.168.10.1";

    char *host_ip[2];
    split_string(my_conf[0], host_ip);

    printf("%s\n",host_ip[0]);
    printf("%s\n",host_ip[1]);
}

I want to modify the host_ip array inside the split_string function and then print the 2 resulting strings in the main.

However, the 2 last printf() are only printing unknown/random characters (maybe an address?). Any help?

4
  • Where are you assigning or allocating memory for the two strings that are the elements of the host_ip[] array? You've declared this array but that's all. Commented Sep 21, 2019 at 16:26
  • I thought that by writing char *my_conf[1] I would create something like: my_conf = ["conf1"]. In other words, I would be creating a pointer that would point to the beginning of an array with 1 value (this value could have any size). Maybe this is not what happens... Commented Sep 21, 2019 at 16:59
  • 3
    sizeof(conf) gives you size of the pointer, not size of what it points to. And sizeof(*conf) would give you size of char, ie. 1. You have to pass the length as parameter, or use strlen in the function. Commented Sep 21, 2019 at 17:21
  • re2c.org/manual/manual.html gives an example of using s-tags to parse an IPv4 IP very nicely. Commented Sep 21, 2019 at 18:14

2 Answers 2

2

There are 2 problems:

First, you're returning pointers to local variables. You can avoid this by strduping the strings and freeing in the caller.

Second:

On the first call to strtok_r(), str should point to the string to be parsed, and the value of saveptr is ignored. In subsequent calls, str should be NULL, and saveptr should be unchanged since the previous call.

I.e. you must NULL for the first argument after the first iteration in the loop. Nowhere is it said that it is OK to use the same pointer for both arguments. This is because the strtok_r is an almost drop-in replacement to the braindead strtok, with just one extra argument, so that you could even wrap it with a macro...

Thus we get

char *start = rest;
while ((token = strtok_r(start, "_", &rest))){
    host_ip[i] = strdup(token);
    printf("-----------\n");
    printf("token: %s\n", token);
    i++;
    start = NULL;  
}

and in the caller:

free(host_ip[0]);
free(host_ip[1]);
Sign up to request clarification or add additional context in comments.

3 Comments

Thank you for the tips. However the problem persists. I want to split the "conf01_192.168.10.1" string and print both substrings "conf01 and "192.168.10." in the main function, which is not possible with my current code structure
@imll did you add the strdup as in my example?!
I added it just now, almost missed it! But why do I have to free host_ip? I'm not creating it using malloc...
1

You are storing address of local variable (line) which is in stack.Stack is LIFO and has valid data for local variables in its stack memory during its function life time.after that, the same stack memory will be allocated to another function's local variables. So, data stores in line【50】's memory will be invalid after coming out of string_split function

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.