繁体   English   中英

字符指针和 malloc

[英]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()更糟糕,因为它从不返回分配的数据,也从不重用它,这相当于直接内存泄漏。

代码应该:

  1. 符合文档并要求消费者代码free()字符串(为了清楚起见,可能将其重命名为get_string_alloc() )。
  2. 提供一个库例程来释放字符串( 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;

  • 不需要 new malloc 因为从 get_string() 函数返回的字符串已经在堆上,您只需要获取指向第一个字符的指针。 get_string() 函数参考

字符串 = get_string();

printf("你好 %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;
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM