【问题标题】:freeing malloc'd memory causes other malloc'd memory to garbage释放 malloc 的内存会导致其他 malloc 的内存成为垃圾
【发布时间】:2018-10-11 17:04:20
【问题描述】:

我正在尝试学习 C,而我发现棘手的事情之一是字符串和操作它们。我想我了解它的基础知识,但我已经理所当然地认为 JS 或 PHP(我来自哪里)中的字符串可能包含很多内容。

我现在正在尝试使用strtok 编写一个基于分隔符将字符串分解为数组的函数。类似于PHP对explode()的实现。

代码如下:

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

char **explode(char *input, char delimiter) {
    char **output;
    char *token;
    char *string = malloc(sizeof(char) * strlen(input));
    char delimiter_str[2] = {delimiter, '\0'};
    int i;
    int delim_count = 0;

    for (i = 0; i < strlen(input); i++) {
        string[i] = input[i];
        if (input[i] == delimiter) {
            delim_count++;
        }
    }
    string[strlen(input)] = '\0';

    output = malloc(sizeof(char *) * (delim_count + 1));
    token = strtok(string, delimiter_str);

    i = 0;
    while (token != NULL) {
        output[i] = token;
        token = strtok(NULL, delimiter_str);
        i++;
    }

    // if i uncomment this line, output gets all messed up
    // free(string);

    return output;
}

int main() {
    char **row = explode("id,username,password", ',');
    int i;

    for (i = 0; i < 3; i++) {
        printf("%s\n", row[i]);
    }

    free(row);
    return 0;
}

我的问题是为什么如果我尝试在函数中使用free(string),输出会变得一团糟,如果我一开始就做错了。我相信我只是没有正确地在脑海中映射出记忆,这就是我不理解这个问题的原因。

【问题讨论】:

  • string[strlen(input)] = '\0'; 超出范围。您忘记为空终止符分配空间。

标签: c memory malloc free


【解决方案1】:

你误解了 strtok 的作用,它不会产生新的字符串,它只是返回一个指向原始字符串不同部分的指针。如果您随后释放该字符串,则您存储的所有指针都将变为无效。我觉得你需要

while (token != NULL) {
    output[i] = strdup(token);
    token = strtok(NULL, delimiter_str);
    i++;
}

strdup 会为你分配和复制一个新的字符串

【讨论】:

  • 如果你这样做,那么在 main 中,你将不得不释放每个字符串,而不仅仅是释放 row 变量。
【解决方案2】:

在output 中,您保存指向string 的指针,因此当您释放string 时,您释放了output 指针指向的内存。

仅保存指针是不够的。您必须复制实际的字符串。为此,您需要以另一种方式为output 分配内存。

【讨论】:

    猜你喜欢
    • 2012-01-07
    • 2021-04-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多