我try 用以下代码解析提供给该方法的查询字符串

char array[] = "address=NYC&port=3359&username=JDoe&password=Secret*";

下面是我的代码(我也包含了这些帮助器方法的代码,因为并非所有的库都包含它们.)

typedef struct { char *key, *value; } keyValuePair_t, *keyValuePair_p;

char* strdup(const char* s) {
    size_t len = strlen(s) + 1;
    void* _new = malloc(len);
    if (_new == NULL)
        return NULL;
    return (char*)memcpy(_new, s, len);
}

char* strsep(char** stringp, const char* delim) {
    char* s;
    const char* spanp;
    int c, sc;
    char* tok;

    if ((s = *stringp) == NULL)
        return (NULL);
    for (tok = s;;) {
        c = *s++;
        spanp = delim;
        do {
            if ((sc = *spanp++) == c) {
                if (c == 0)
                    s = NULL;
                else
                    s[-1] = 0;
                *stringp = s;
                return (tok);
            }
        } while (sc != 0);
    }
}

keyValuePair_p* queryStringProcessor(const char* array) {
    char* query = strdup(array);
    char* tokens = query;
    char* p = query;
    keyValuePair_p* ret = NULL;
    unsigned char counter = 0;

    while ((p = strsep(&tokens, "&\n"))) {
        char* var = strtok(p, "="), *val = NULL;
        if (var && (val = strtok(NULL, "="))) {
            ret = (keyValuePair_p*)realloc(ret, (counter + 1)*sizeof(keyValuePair_p));
            ret[counter] = (keyValuePair_p)calloc(1, sizeof(keyValuePair_t));
            ret[counter]->key = var;
            ret[counter]->value = val;
            ++counter;
        }
    }
    free(query);
    return ret;
}

问题是,queryStringProcessor运行得很好,它生成的键-值对也很好,但是当执行free(query)时,整个键-值对数组就变坏了,我不知道为什么.我在Windows下的VS2022上对其进行了测试. 谢谢你的帮忙!

推荐答案

您直接将指向keyValuePair_t struct 的键和值字段的指针赋给从strtok获得的令牌.由于strtok不为标记分配新的内存,而是就地修改原始字符串,因此当您释放原始查询字符串时,实质上也释放了保存键和值的内存.

您可以通过以下方式进行简单的修改,但please free the memory of the key/value:

keyValuePair_p* queryStringProcessor(const char* array) {
    char* query = strdup(array);
    char* tokens = query;
    char* p = query;
    keyValuePair_p* ret = NULL;
    unsigned char counter = 0;

    while ((p = strsep(&tokens, "&\n"))) {
        char* var = strtok(p, "="), *val = NULL;
        if (var && (val = strtok(NULL, "="))) {
            ret = (keyValuePair_p*)realloc(ret, (counter + 1)*sizeof(keyValuePair_p));
            ret[counter] = (keyValuePair_p)malloc(sizeof(keyValuePair_t));
            ret[counter]->key = strdup(var); // Allocate memory for key and copy var
            ret[counter]->value = strdup(val); // Allocate memory for value and copy val
            ++counter;
        }
    }
    free(query);
    return ret;
}

C++相关问答推荐

为什么海湾合作委员会在共享对象中的. init_data的虚拟内存地址之前留出一个空白

找出文件是否包含给定的文件签名

C/SDL程序,渲染不使用我的渲染器

__VA_OPT__(,)是否可以检测后面没有任何内容的尾随逗号?

如何将字符串argv[]赋给C中的整型数组?

C语言中的strstr问题

Rust FFI--如何用给出返回引用的迭代器包装C风格的迭代器?

如何在ASM中访问C struct 成员

限制不同类型的限定符

Printf()在C中打印终止字符之后的字符,我该如何解决这个问题?

将数字的每一位数平方,并使用C将它们连接为一个数字(程序不能正确处理0)

C:Assignment中的链表赋值从指针目标类型中丢弃‘const’限定符

生产者消费者计数器意外输出的C代码

对于STM32微控制器,全局偏移表.get和.Got.plt必须为零初始化

If语句默认为true

Ubuntu编译:C中的文件格式无法识别错误

如何用用户输入的多个字符串填充数组?

是什么阻止编译器优化手写的 memcmp()?

使用复合文字数组初始化的指针数组

在链表中插入一个值