我对char指针的概念有点混淆,因此我制作了一个简单的代码,只是打印了用户提供的名字(我)。我也想练习malloc,因此我在RAM中引用了指向某个内存的指针,但是我真的不知道要在" sizeof(char) *"之后放置什么,因为那是用户输入,尚未决定。另外,这样做之后,我释放了内存,但是我在命令行上收到了一条错误消息:
*** Error in `./char': double free or corruption (fasttop): 0x00000000017fe030 ***
Aborted
似乎我两次释放了同一内存,但我不知道该删除或添加什么。请帮助!
#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 %sn", strings);
free (strings);
return 0;
}
行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..
}
好的练习将有:
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...
}
然后称为get_string(strings,10);
。
编辑:进行了一些研究后,已经确定了缺陷。get_string()
不直接free()
它返回的字符串,而是将其添加到库中释放的库的分配列表中(以atexit()
注册的 teardown()
或其他编译器依赖性功能为CC_13)。
这是糟糕的设计,因为没有提供消费者代码,没有安全的方法可以释放内存,而在典型的用例中,整个应用程序执行不需要。get_double()
更糟,因为它永远不会返回分配的数据,但永远不会重复使用它,并且等于直率的内存泄漏。
代码应:
- 符合文档,要求消费者代码来
free()
字符串(也许将其重命名为get_string_alloc()
,以清楚地清楚)。 - 提供库例程以释放字符串(
get_new_string()
和release_string()
)
没有一个很好的方法可以改变C中分配的内存所有权,但是在其余执行中坚持下去绝对不是答案。许多图书馆都四处乱逛,将分配推向消费者代码,但是当不知道所需的整个空间时,这是繁重的。
。我建议将_alloc()
放在任何返回对象的末尾,消费者代码必须以后free()
。
因此,提出的问题的答案是删除malloc()
和free()
,因为库都可以处理两者。但是,请注意,如果您的程序对该功能进行了许多呼叫,并且其他内部依赖它的函数(如get_double()
),您可能会因为库坐在死空间而用完。
问题是您的get_strings
覆盖您的初始malloc
。指针值是一个值。通过将其等同于其他内容,您替换您的malloc
值。
记忆在语句中分配:
strings = get_string();
您不必malloc
IT(char *strings = malloc(sizeof(char) * 10);
)
没有malloc
,它将正常工作
首先,您创建了一个动态内存,该内存将由*strings 指向。但是,然后您使用*strings 指针指向本地字符串(从get_string()函数)。当您免费致电时,程序正在尝试删除本地(堆栈)参考和投掷错误。
要解决该错误,该程序应为
#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
strcpy(strings, get_string()); // Use strcpy instead of assigning
printf("Hello %sn", strings);
free (strings);
return 0;
}
您不包含get_string()
的代码,但是您的返回值是错误的。您传递给free()
的地址必须来自malloc()
,看来您违反了(除了失去10个字节的原始返回地址)。
假设get_string()
返回静态存储(即您不需要释放它),您可以执行此操作而无需涉及malloc()
。
如果您真的想要,那么类似的事情可能有效:
printf("What is your name?n");
const char *name = get_string();
const size_t nlen = strlen(name);
char * const name_copy = malloc(nlen + 1);
if(name_copy != NULL)
{
memcpy(name_copy, name, nlen + 1);
printf("Hello %s (from my own memory!)n", name_copy);
free(name_copy);
}
这很复杂,但是您明白了。
char *strings;
- 不需要新的malloc,因为从get_string()函数返回的字符串已经在堆上,您只需要在第一个字符上选择指针即可。(get_string()函数参考)
strings = get_string();
printf(" hello%s n",strings);
- 打印字符串后,您应该免费为其分配内存,因为它在get_string()函数参考中所述
将字符串存储在堆上(通过malloc);必须由呼叫者释放内存 避免泄漏。
我认为其他一切都很好,请尝试以下代码:
#include <stdio.h>
#include <cs50.h>
int main (void)
{
char *strings;
printf("What is your name?n");
//wait for use to type his/her name
strings = get_string();
printf("Hello %sn", strings);
free (strings);
return 0;
}