c - 全部释放内存吗?

标签 c

可能是个糟糕的话题,但是考虑到下面的代码,我是否也需要free(player->name)

#include <stdio.h>

struct Player
{
       char *name;
       int level;       
};

int main()
{
    struct Player *player;
    player->name = malloc(sizeof(player->name)*256);
    player->name = "John";

    printf(player->name);

    free(player);

    printf("\n\n\n");
    system("PAUSE");
    return 0;
}

最佳答案

天哪,从哪里开始?你真的需要一本好书。叹息。让我们从main()的顶部开始:
这个

struct Player *player;

定义指向struct Player的指针,但它不初始化它因此它有一个或多或少的随机值,指向内存的某个地方。这个
player->name = malloc(sizeof(player->name)*256);

现在将malloc()获得的内存地址写入该随机位置的一部分通过未初始化的指针写入内存会调用未定义的行为。在那之后,所有的赌注都被取消了。不用再看你的程序了你不走运的是,意外地,你给进程拥有的一段内存写信,所以它不会立即崩溃,让你意识到这个问题。
有两种方法可以让你改进。要么抓住指针,让它指向为Player对象分配的内存。您可以通过调用malloc(sizeof(Player)获得它。
或者只使用一个本地的、自动的(也就是基于堆栈的)对象:
struct Player player;

编译器将生成代码来为它在堆栈上分配内存,并自动释放它。这是最简单的,当然也应该是你的默认。
但是,您的代码还有更多的问题。
这个
player->name = malloc(sizeof(player->name)*256);

在堆上分配连续内存以存储256个指向字符的指针,并将第一个指针的地址(achar*,因此achar**)分配给player->name(achar*)坦率地说,我很惊讶,甚至编译,但我更习惯于C++更严格的类型执行。无论如何,您可能需要的是为256个字符分配内存:
player->name = malloc(sizeof(char)*256);

(因为根据定义,sizeof(char)1,所以您通常将其视为malloc(256)
然而,还有更多的问题:为什么是256如果我传递1000个字符长的字符串呢不,简单地为一个较长的字符串分配空间并不是解决这个问题的方法,因为我仍然可以向它传递一个更长的字符串因此,1)将最大字符串长度(只要声明为“cc>为该长度的Player::name数组,而不是char”,并在代码中强制执行此限制,或2)在运行时动态查找所需的长度,并精确分配所需的内存(字符串长度加1,用于终止char* char)。
但情况越来越糟这个
player->name = "John";

然后将字符串文本的地址赋给'\0',覆盖player->name在存储它的唯一变量中分配的内存地址,使内存丢失并泄漏。
但是字符串在C语言中不是一等公民,所以不能赋值它们是字符数组,按惯例以malloc()结尾。要复制它们,必须逐个字符地复制它们,可以是循环复制,或者最好是通过调用'\0'
雪上加霜的是,你后来试图释放一个字符串的记忆
free(player);

因此很可能会严重扰乱堆管理器的数据结构。同样,你似乎不太走运,没有立即导致崩溃,但代码似乎按预期工作,这是未定义行为最糟糕的表现形式之一如果不是所有的赌注都被取消了,他们现在就彻底结束了。
我很抱歉,如果这听起来是谴责,它真的不是那样的意思,但你肯定和严重地搞砸了这个。总结一下:
你需要一本好的C++书籍。马上。Here是C程序员在堆栈溢出时汇编的一系列好书(我是一个C++程序员,所以我不会评论他们的判断,但K&R确实是一个不错的选择。)
您应该立即初始化所有指针,要么用现有有效对象的地址,要么用分配给保存一个正确类型对象的内存的地址,或者用strcpy()(稍后您可以很容易地检查)。特别是,您不能试图读取或写入尚未分配给您的内存(动态地在堆上或自动地在堆栈上)。
您需要精确调用一次NULL获得的所有内存。
您不能试图free()任何其他内存。
我相信还有更多的代码,但我会停在这里我说过你需要一本好的C书吗?因为你知道。

关于c - 全部释放内存吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7497658/

相关文章:

c - 用于一维 double 据数组的简单 ANSI C 直方图函数?

c - 在 C 中传递二维数组的行

c - 使用 strstr 确定给定字符串是否包含带空格的字符串 [C]

c - FFT - 在 PCM 数据上应用窗口

c - 错误 C2143 : syntax error : missing ';' before ')'

java - JNI 无法在 NetBeans 上检测到 __int64

c - 代码中这个以 ":"结尾的元素是什么意思?

c - STM32 I2C1 起始位未在 SR1 寄存器上设置

c++ - 指针表达式 : *ptr++, *++ptr 和++*ptr

使用一维数组创建二维整数数组