在结构上调用 free 会引发运行时错误

标签 c struct function-pointers free

我创建了一个基于 Simple Object System 的简单对象系统然后我决定通过添加一个函数来扩展代码,以在怪物死亡时释放有关怪物的所有内存:

void Monster_destroy(void *self)
{
    Monster* monster=self;
    if(&(monster->proto))
        free(&(monster->proto));
    free(monster);
}

我在这里使用这个函数是这样的:

int Monster_attack(void* self,int damage)
{
    Monster* monster=self;
    char* desc=monster->proto.description;
    printf("You attack %s!\n", desc);
    monster->hit_points-=damage;
    if(monster->hit_points>0)
    {
        printf("It is still alive\n");
        return 0;
    }
    else
    {
        printf("It is dead\n");
        monster->proto.destroy(monster);
        return 1;
    }       
}

我收到以下错误:

==4699== Invalid free() / delete / delete[] / realloc()
==4699==    at 0x4C2B83A: free (vg_replace_malloc.c:468)
==4699==    by 0x40080F: Monster_destroy (ex19.c:15)
==4699==    by 0x400A2C: Room_attack (ex19.c:96)
==4699==    by 0x400ACA: Map_attack (ex19.c:118)
==4699==    by 0x400E20: process_input (ex19.c:175)
==4699==    by 0x400F52: main (ex19.c:211)
==4699==  Address 0x51fd500 is 0 bytes inside a block of size 56 free'd
==4699==    at 0x4C2B83A: free (vg_replace_malloc.c:468)
==4699==    by 0x400803: Monster_destroy (ex19.c:14)
==4699==    by 0x400A2C: Room_attack (ex19.c:96)
==4699==    by 0x400ACA: Map_attack (ex19.c:118)
==4699==    by 0x400E20: process_input (ex19.c:175)
==4699==    by 0x400F52: main (ex19.c:211)
==4699== 

我有一个系统,怪物看起来像这样:

struct Monster
{
    Object proto;
    int hit_points;
};

typedef struct Monster Monster;

Object 是一个如下所示的结构:

typedef struct
{
    char *description;
    int (*init)(void *self);
    void (*describe)(void* self);
    void (*destroy)(void* self);
    void* (*move)(void* self,Direction direction);
    int (*attack)(void* self,int damage);
}Object;

这就是我现在使用 `Monster_destroy 的方式:

 if(monster && monster->hit_points>0)
{
    monster->proto.attack(monster,damage);
    return 1;
}
else
{
           //dont even call Monster_attack because Monster has no hit_points
    printf("You flail at the air and hit nothing,Idiot\n");
    if(monster)
    monster->proto.destroy(monster);
    return 0;
}

最佳答案

在你的struct Monster中,protoObject而不是Object *

因此在 Monster_destroy() 函数中这样释放内存是无效的。

if(&(monster->proto))
    free(&(monster->proto));

事实上,您没有专门为 proto 分配内存,因此不需要释放它。

但是,如果您为 proto->description 分配了内存,那么您需要使用 free(proto->description) 释放它。

关于在结构上调用 free 会引发运行时错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20562087/

相关文章:

C 新手 : Help with Simple Function

c - 为什么gets 函数如此危险以至于不应该使用它?

c - 将数据存储在头文件中包含数组的 Stucts 中

c - C语言设计问题

java - 如何在lambda表达式中调用方法

具有函数指针常量数组的 C++ 模板化静态类

c - !isdigit 不起作用(C 编程)

结构的c++ vector 和从文件中读取

c++ - 在同一个类中调用函数指针

c - 全局常量与#define。从安全角度来看哪个更好?