Char Pointers和malloc

Jas*_*son 0 c malloc pointers char cs50

我对char指针的概念有点困惑,所以我创建了一个简单的代码,只打印用户(我)提供的名字.我也想练习malloc,所以我引用了指向RAM中某个内存的指针,但我真的不知道在"sizeof(char)*"后要放什么,因为这是用户输入,尚未确定.此外,在执行此操作后,我释放了内存,但我在命令行上收到一条错误消息:

*** Error in `./char': double free or corruption (fasttop): 0x00000000017fe030 ***
Aborted
Run Code Online (Sandbox Code Playgroud)

好像我释放了相同的内存两次或者什么,但我不知道要删除或添加什么.请帮忙!

#include <stdio.h>
#include <cs50.h>

int main (void)
{

    char *strings = malloc(sizeof(char) * 10);


    printf("What is your name?\n");

    //wait for use to type his/her name
    strings = get_string();


    printf("Hello %s\n", strings);

    free (strings);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

Per*_*xty 6

该行strings = get_string();实际分配返回的值get_string()strings.它不会将其写入您分配的内存中.

因此,返回的价值malloc()已被覆盖(在这种情况下丢失).

free(strings)被释放任何get_string()返回.这个问题没有为此提供代码,但可能是它无效free().

因为运行时告诉你它被释放了两次我猜你已经分配了内存get_string()然后释放它并返回一个无效的指针.

如果要使用分配的内存,则需要更改get_string()为接受指针:

void get_string(char *str){
    //Do whatever writing you value into str[] as an array of char..
}
Run Code Online (Sandbox Code Playgroud)

良好做法会:

void get_string(char *str, size_t max){
    //Do whatever writing you value into str[] as an array of char..
    //Use max to avoid writing beyond the end of the space allocated...
}
Run Code Online (Sandbox Code Playgroud)

然后打电话给get_string(strings,10);.

编辑:经过一些研究后发现了这个漏洞.get_string()它不会直接free()返回它返回的字符串,而是将其添加到库所做的分配列表中,这些分配在退出时释放(在一个名为teardown()registered with atexit()或其他编译器相关功能的函数中).

这是糟糕的设计,因为消费者代码没有提供自己释放内存的安全方式,在整个应用程序执行中不需要典型的用例.get_double()更糟糕的是因为它永远不会返回分配的数据,但从不重用它,相当于直接的内存泄漏.

代码应该是:

  1. 符合文档并要求消费者代码到free()字符串(get_string_alloc()为清楚起见,可能将其重命名为).
  2. 提供一个库例程来释放字符串(get_new_string()release_string())

没有非常好的方法可以在C中转移已分配内存的所有权,但在执行的剩余时间内保留它绝对不是答案.许多图书馆围绕房屋推进分配到消费者代码,但是当所需空间的全部大小无法知道时,这是繁重的.

我建议放在_alloc()任何返回消费者代码必须稍后的对象的函数的末尾free().

所以提出的问题的答案是删除malloc()free()因为库处理两者.但是请注意,如果您的程序对该函数进行了多次调用,而其他内部依赖它(例如get_double()),则可能因为库位于死区而耗尽内存.

  • 显然,根据您使用的cs50的版本,[库可以从`get_string`管理自己的堆分配链](https://github.com/cs50/libcs​​50/blob/develop/docs/get_string.adoc) ,并在进程退出时释放它们(毫无意义的保存为良好实践,因为操作系统将回收所有内存,无论如何).这样做,如果在用户代码中也完成了双重自由.不同版本的库不会这样做.所以有人按照旧的教程编写代码,使用较新的lib,会产生双重免费.这可能就是这里发生的事情. (3认同)