Char指针和malloc
我对字符指针的概念有点困惑,所以我编写了一个简单的代码,只打印用户(我)提供的我的名字。我还想练习malloc,所以我引用了指向RAM中某个内存的指针,但我真的不知道在“sizeof(char)*”之后放什么,因为这是用户输入,还没有决定。 此外,在执行此操作后,我释放了内存,但在命令行上收到一条错误消息,上面说:Char指针和malloc,c,pointers,char,malloc,cs50,C,Pointers,Char,Malloc,Cs50,我对字符指针的概念有点困惑,所以我编写了一个简单的代码,只打印用户(我)提供的我的名字。我还想练习malloc,所以我引用了指向RAM中某个内存的指针,但我真的不知道在“sizeof(char)*”之后放什么,因为这是用户输入,还没有决定。 此外,在执行此操作后,我释放了内存,但在命令行上收到一条错误消息,上面说: *** Error in `./char': double free or corruption (fasttop): 0x00000000017fe030 *** Aborted
*** 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;
}
#包括
#包括
内部主(空)
{
char*strings=malloc(sizeof(char)*10);
printf(“您叫什么名字?\n”);
//等待使用以键入他/她的姓名
strings=get_string();
printf(“Hello%s\n”,字符串);
自由(字符串);
返回0;
}
您没有包含get_string()
的代码,但是您正在用其返回值覆盖字符串,这是错误的。您传递给free()
的地址必须来自malloc()
,而且您似乎违反了这一点(除了丢失10字节的原始返回地址)
假设get\u 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);
}
这相当复杂,但你明白了。问题是你的get\u字符串
覆盖了你的初始malloc
。指针值是一个值。通过将其与其他内容等同,您替换了malloc
值 首先,您创建了一个动态内存,它将由*字符串指向。但是,然后使用*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;
}
#包括
#包括
内部主(空)
{
char*strings=malloc(sizeof(char)*10);
printf(“您叫什么名字?\n”);
//等待使用以键入他/她的姓名
strcpy(strings,get_string());//使用strcpy而不是赋值
printf(“Hello%s\n”,字符串);
自由(字符串);
返回0;
}
行strings=get_string()
实际将get_string()
返回的值赋给strings
。它不会将其写入您分配的内存中
因此,malloc()
返回的值已被覆盖(在本例中丢失)
free(strings)
正在释放返回的get\u string()。这个问题没有提供相应的代码,但假定它对free()
it无效
因为运行时告诉您它被释放了两次,我猜您在get\u string()
中分配了内存,然后释放了它并返回了无效指针
如果要使用分配的内存,需要更改get\u 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...
}
然后调用asget_string(strings,10)代码>
编辑:经过一番研究,该缺陷已被识别get_string()
不会直接free()
它返回的字符串,而是将其添加到库所做的分配列表中,这些分配在退出时被释放(在一个名为teardown()
的函数中,该函数使用atexit()
或其他编译器相关功能注册)
这是糟糕的设计,因为消费者代码本身没有提供安全的方式来释放内存,在典型的用例中,整个应用程序的执行都不需要内存get_double()
更糟糕,因为它从不返回分配的数据,但从不重用它,这直接导致内存泄漏
该守则应:
符合文档要求,并要求消费者代码free()
字符串(为了清晰起见,可以将其重命名为sayget\u string\u alloc()
)
提供一个库例程来释放字符串(获取新字符串()
和释放字符串()
)
在C语言中,没有很好的方法来转移已分配内存的所有权,但在执行的剩余时间内保持它绝对不是解决办法。
许多图书馆在房子里四处奔走,将分配工作纳入消费者法规,但当所需空间的完整大小无法得知时,这是一项繁重的工作,比如这里
我建议将\u alloc()
放在任何函数的末尾,该函数返回用户代码以后必须释放()的对象
因此,所提出问题的答案是删除malloc()
和free()
,因为库同时处理这两个函数。但是,请注意,如果您的程序多次调用该函数以及其他内部依赖该函数的函数(如get_double()
),则可能会因为库位于死区而耗尽内存。内存是在语句处分配的:
strings=get_string()代码>
您不必malloc
it(char*strings=malloc(sizeof(char)*10);
)
没有malloc
它可以很好地工作char*字符串代码>
- 不需要新的malloc,因为从get_string()函数返回的字符串已经在堆上,您只需要拾取指向第一个字符的指针。()
strings=get_string()
printf(“Hello%s\n”,字符串)
- 打印字符串后,您应该释放分配给它的内存,如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 %s\n", strings);
free (strings);
return 0;
}
#包括
#包括
内部主(空)
{
字符*字符串;
printf(“您叫什么名字?\n”);
//等待使用以键入他/她的姓名
串