【问题标题】:Wrong output after modifying an array in a function (in C)修改函数中的数组后输出错误(在 C 中)
【发布时间】:2019-09-21 16:21:27
【问题描述】:

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

我想修改 split_string 函数中的 host_ip 数组,然后在 main.xml 中打印 2 个结果字符串。

但是,最后 2 个 printf() 仅打印未知/随机字符(可能是地址?)。有什么帮助吗?

【问题讨论】:

  • 您在哪里为host_ip[] 数组元素的两个字符串分配或分配内存?你已经声明了这个数组,但仅此而已。
  • 我认为通过写char *my_conf[1] 我会创建类似:my_conf = ["conf1"]。换句话说,我将创建一个指针,该指针将指向具有 1 个值的数组的开头(该值可以具有任何大小)。也许这不是发生的事情......
  • sizeof(conf) 给你指针的大小,而不是它指向的大小。 sizeof(*conf) 会给你 char 的大小,即。 1. 必须将长度作为参数传递,或者在函数中使用strlen
  • re2c.org/manual/manual.html 给出了一个使用 s-tags 很好地解析 IPv4 IP 的示例。

标签: c function


【解决方案1】:

有2个问题:

首先,您将返回指向局部变量的指针。你可以通过strduping 字符串并在调用者中释放来避免这种情况。

第二:

在第一次调用strtok_r() 时,str 应该指向要解析的字符串,saveptr 的值被忽略。在随后的调用中,str 应该是NULL,并且saveptr 应该自上次调用以来保持不变。

you must NULL for the first argument after the first iteration in the loop. 没有地方说可以对两个参数使用 same 指针。 这是因为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]);

【讨论】:

  • 感谢您的提示。然而问题依然存在。我想在主函数中拆分“conf01_192.168.10.1”字符串并打印两个子字符串“conf01”和“192.168.10。”,这在我当前的代码结构中是不可能的
  • @imll 你是否像我的例子一样添加了strdup?!
  • 刚刚加了,差点错过!但是为什么我必须释放host_ip?我没有使用 malloc 创建它...
【解决方案2】:

您正在存储堆栈中的局部变量(行)的地址。堆栈是 LIFO 并且在其函数生命周期内其堆栈内存中的局部变量的有效数据。之后,相同的堆栈内存将分配给另一个函数的局部变量。所以,第【50】行内存中的数据在退出string_split函数后会失效

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-10
    • 2015-06-21
    • 1970-01-01
    • 1970-01-01
    • 2021-06-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多