[英]Char Pointers and malloc
我对字符指针的概念有点困惑,所以我做了一个简单的代码,只是打印用户(我)提供的名字。 我也想练习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 %s\n", 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()
它返回的字符串,而是将它添加到库所做的分配列表中,这些分配在退出时释放(在一个名为teardown()
的函数中注册atexit()
或其他编译器相关功能) .
这是糟糕的设计,因为消费者代码没有提供安全的方式来释放内存,在典型的用例中,整个应用程序执行不需要。 get_double()
更糟糕,因为它从不返回分配的数据,也从不重用它,这相当于直接内存泄漏。
代码应该:
free()
字符串(为了清楚起见,可能将其重命名为get_string_alloc()
)。get_new_string()
和release_string()
)没有很好的方法来转移 C 中已分配内存的所有权,但在执行的其余部分保留它绝对不是答案。 许多图书馆绕过房屋将分配推到消费者代码上,但是当无法知道所需空间的完整大小时,例如这里,这是繁重的。
我建议将_alloc()
放在任何返回消费者代码稍后必须free()
对象的函数的末尾。
因此,所提出问题的答案是删除malloc()
和free()
因为库同时处理这两者。 但是请注意,如果您的程序多次调用该函数以及其他内部依赖它的函数(例如get_double()
),您可能会因为库位于死空间而耗尽内存。
问题是您的get_strings
覆盖了您的初始malloc
。 指针值是一个值。 通过将它等同于其他东西,您替换了malloc
值。
您没有包含get_string()
的代码,但是您正在用错误的返回值覆盖strings
。 您传递给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);
}
这是相当复杂的,但你明白了。
首先,您已经创建了一个由*strings指向的动态内存。 但是随后您使用*strings指针指向本地字符串(来自 get_string() 函数)。 当您调用 free 时,程序正在尝试删除本地(堆栈)引用并抛出错误。
为了解决这个错误,程序应该是
#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 %s\n", strings);
free (strings);
return 0;
}
内存在以下语句中分配:
strings = get_string();
您不必对其进行malloc
( char *strings = malloc(sizeof(char) * 10);
)
没有malloc
它会正常工作
char *strings;
字符串 = get_string();
printf("你好 %s\\n", 字符串);
在堆上存储字符串(通过 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 %s\n", strings);
free (strings);
return 0;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.