Неверный вывод после изменения массива в функции (в C) - PullRequest
0 голосов
/ 21 сентября 2019

Я новичок в C и у меня проблемы со следующим кодом:

#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]);
}

Я хочу изменить массив host_ip внутри функции split_string, а затем распечатать 2 результирующие строки в главном,

Однако последние 2 функции printf () печатают только неизвестные / случайные символы (может быть, адрес?).Любая помощь?

Ответы [ 2 ]

2 голосов
/ 21 сентября 2019

Есть 2 проблемы:

Во-первых, вы возвращаете указатели на локальные переменные.Вы можете избежать этого, strdup вводя строки и освобождая в вызывающем.

Second:

При первом вызове strtok_r(), str должен указывать наанализируемая строка, а значение saveptr игнорируется.В последующих вызовах str должно быть NULL, а saveptr должно оставаться неизменным с момента предыдущего вызова.

Т.е. вы должны NULL для первого аргумента после первой итерации в цикле. Нигде не сказано, что можно использовать то же самое указатель на оба аргумента.Это потому, что strtok_r является почти заменой мозгового мертвого strtok с одним дополнительным аргументом, чтобы вы могли даже обернуть его макросом ...

Таким образом, мы получаем

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

и в вызывающей стороне:

free(host_ip[0]);
free(host_ip[1]);
1 голос
/ 21 сентября 2019

Вы храните адрес локальной переменной (строки), которая находится в стеке. Стек является LIFO и содержит действительные данные для локальных переменных в своей памяти стека в течение времени жизни функции. После этого та же самая память стека будет выделена другойлокальные переменные функции.Таким образом, хранилища данных в памяти строки 50 будут недействительными после выхода из функции string_split

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...