Char指针和malloc

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

我对字符指针的概念有点困惑,所以我编写了一个简单的代码,只打印用户(我)提供的我的名字。我还想练习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;
}
#包括
#包括
内部主(空)
{
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...
}
然后调用as
get_string(strings,10)

编辑:经过一番研究,该缺陷已被识别
get_string()
不会直接
free()
它返回的字符串,而是将其添加到库所做的分配列表中,这些分配在退出时被释放(在一个名为
teardown()
的函数中,该函数使用
atexit()
或其他编译器相关功能注册)

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

该守则应:

  • 符合文档要求,并要求消费者代码
    free()
    字符串(为了清晰起见,可以将其重命名为say
    get\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”);
    //等待使用以键入他/她的姓名
    串