【问题标题】:String turns to garbage after using free()使用 free() 后字符串变成垃圾
【发布时间】:2015-09-24 01:45:39
【问题描述】:

我使用 typedef person_t 在 person 结构中创建一个人:

int main(int argc, char* argv[]) {
    person_t a;
    memset(&a, 0, sizeof(person_t));

    person_set_name(&a, "Konrad Hoppenstauffer");
    person_set_age(&a, 42);

void person_set_name(person_t* person, char* name) {
    if(person->name) {
        free(person->name);
    }
    person->name = malloc(sizeof(char) * strlen(name) + 1);
    strcpy(person->name, name);
}

上面的效果很好。

使用此功能时出现问题:

person_t* string_to_person(char* str) { 
    person_t* person = malloc(sizeof(person_t));

    int len = 0;
    while(str[len] != '\t') {
        len++;
    }

    char* name = malloc(len + 1);

    int i;
    for(i = 0; i < len; i++) {
        name[i] = str[i];
    }
    name[len] = '\0';

    person_set_name(person, name);
    person_set_age(person, atoi(str+len+1));

    return person;
}

这里的 str 类似于:“Name Nameson\t22”。那是由制表符分隔的名称。然后我将两者分开并将字符放入 char* 名称中。

person_t 是结构的 typedef。

如果我从 person_set_name 中删除 free(person->name),一切正常。但是如果我把它留在里面,名字就会变成垃圾,例如:“É8>”。

我假设在复制每个字符的 for 循环中发生了错误。但是以我对 C 语言的有限经验,我看不出是什么。感谢您的帮助。

【问题讨论】:

  • 我不认为这会导致您所问的问题,但是您在没有初始化结构的情况下检查 person->name 是否为 NULL,malloc 不会为您初始化它。
  • 我说的是string_to_person
  • 这修复了它:memset(person, 0, sizeof(person_t));谢谢

标签: c for-loop free char-pointer


【解决方案1】:

你正在尝试释放一个垃圾指针。

之后:

person_t* person = malloc(sizeof(person_t));

malloc 不会使用任何特定数据初始化新内存块,因此您的程序此时必须将*person 视为包含垃圾(因为它可能包含任何数据)。特别是,person-&gt;name(即(*person).name)可能不是NULL

不久之后,这段代码运行:

if(person->name) {
    free(person->name);
}

- 如果person-&gt;name 不是NULL,那么你释放它。由于person-&gt;name 没有指向您使用malloc 分配的东西,所以此时您已经完全处于Undefined Behavior Land™ 中了。

一种可能的解决方法是在分配人员后立即设置person-&gt;name = NULL;

【讨论】:

    猜你喜欢
    • 2013-02-07
    • 2010-11-22
    • 1970-01-01
    • 1970-01-01
    • 2011-01-21
    • 2015-01-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多