释放C库中的静态结构

释放C库中的静态结构,c,matlab,static,structure,mex,C,Matlab,Static,Structure,Mex,我正在从事的一个项目涉及一个飞行器,其GNC代码写在C库(.out)中。我们必须以.out库的形式从LabVIEW(主要航空电子软件)调用此C代码,并且该软件的性质要求在连续调用函数之间使用静态指针存储数据。我们在整个飞行过程中定期调用GNC执行函数。我现在尝试在Windows上的DLL中使用Matlab MEX包装器调用此函数,这发现了一些内存管理问题 我在函数开头声明如下结构: static Nav_str *Nav_IN_OUT_ptr; static hguid_ref *Guid_I

我正在从事的一个项目涉及一个飞行器,其GNC代码写在C库(.out)中。我们必须以.out库的形式从LabVIEW(主要航空电子软件)调用此C代码,并且该软件的性质要求在连续调用函数之间使用静态指针存储数据。我们在整个飞行过程中定期调用GNC执行函数。我现在尝试在Windows上的DLL中使用Matlab MEX包装器调用此函数,这发现了一些内存管理问题

我在函数开头声明如下结构:

static Nav_str *Nav_IN_OUT_ptr;
static  hguid_ref *Guid_IN_OUT_ptr;
static  HopControl *Control_IN_OUT_ptr;

Nav_IN_OUT_ptr = (Nav_str *)malloc(sizeof(Nav_str));
Guid_IN_OUT_ptr = (hguid_ref *)malloc(sizeof(hguid_ref));
Control_IN_OUT_ptr = (HopControl *)malloc(sizeof(HopControl));
这在函数的每次运行期间都会发生。但是,在多次迭代调用此函数后,它总是在尝试退出后因内存分段错误而崩溃。我的理解是,这段记忆应该会自我清理,对吗

为了手动清理,我在末尾添加了以下行,仅在清理迭代中调用:

free(Nav_IN_OUT_ptr);
free(Guid_IN_OUT_ptr);
free(Control_IN_OUT_ptr);

这是释放内存的正确方法吗?我能释放这个内存吗?除了C在最后一次调用后没有正确地放弃内存,或者Matlab没有正确地管理其内存之外,分割错误可能还有其他原因吗?我已经到处搜索有类似问题的人(甚至联系Mathworks),但运气不好,所以如果有任何评论或建议,我将不胜感激。

如果无法释放内存,不会导致分段错误。很可能你的问题出在别的地方。两种可能的情况是:

  • 溢出缓冲区
  • 使用指向以前已释放的内存的指针
  • 使用了错误的指针值,但设置不正确
  • 尝试释放malloc'd未返回(或已释放)的指针

  • 我的理解是这段记忆 应该把自己清理干净,是吗 这不对吗

    是的,您需要调用
    free()
    将内存释放回堆。我还建议您在空闲后将指针值设置为
    null
    ,这可以帮助您从上面捕获条件2


    这个代码声明有问题。什么是
    Nav_str
    类型?你确定你不是想使用strlen(Nav_str)+1



    我还需要问,使指针保持静态的目的是什么?静态函数变量基本上是全局变量,仅在极少数情况下使用。

    您的代码确实存在内存泄漏-它是在每次调用函数时分配内存。即使您当前的方法仍然存在内存泄漏-如果在最后一次迭代中只调用一次
    free()
    ,那么您只释放了最近的分配

    但是,内存泄漏通常不会导致分段错误(除非内存泄漏耗尽所有可用内存,导致后续的
    malloc()
    调用返回
    NULL

    如果希望静态结构只分配一次并重复使用,则根本不需要使用
    malloc()
    ,只需将声明更改为:

    static Nav_str Nav_IN_OUT;
    static hguid_ref Guid_IN_OUT;
    static HopControl Control_IN_OUT;
    
    。。。并使用
    Nav_IN_OUT.field
    代替
    Nav_IN_OUT_ptr->field
    ,并使用
    代替
    Nav_IN_OUT_ptr
    (如果您直接将指针值传递给其他函数)

    我的理解是,这段记忆应该会自我清理,对吗

    很抱歉,您错了。:)使用
    malloc()
    分配的内存将一直保留,直到您使用
    free()
    手动删除它。(你最终做对了。万岁。)

    这是释放内存的正确方法吗?我能释放这个内存吗

    这是释放内存的正确方法,但它可能不在正确的位置。通常,在编写
    malloc()
    调用的同时,尝试编写
    free()
    调用

    也许您在函数开始时分配,然后在函数结束时释放。(在这种情况下,如果仅由原始函数调用的函数使用内存,则堆栈内存使用可能更好。)

    也许您有一个
    foo_init()
    函数,该函数调用
    malloc()
    并从API创建关联的上下文,然后将该上下文传递到对该数据进行操作的其他例程中,然后您需要将
    free()
    调用放入
    foo_destroy()
    foo_free()
    或类似例程中。然后,所有调用者都需要平衡
    foo_init()
    foo_free()
    调用。如果您不能只在一个函数中编写
    foo\u init()
    foo\u destroy()
    调用,那么这将特别合适;比如说,您的对象可能需要在更大的事件循环中的某个随机点被删除

    也许数据应该只分配一次,并且永远有效。这对于某些应用程序设计来说是正确的,仅从变量名很难判断这些数据块是否应该永久存在

    除了C不给出之外,是否还有其他原因导致分段错误 在最后一次调用后正确地启动内存,还是Matlab没有正确地管理其内存

    当然有可能;可能这个内存返回得太快,可能某个指针被
    free()
    ed两次或更多次,或者您正在覆盖缓冲区(即
    malloc(sizeof(Nav_str))
    调用有点令人担忧;它可能只是根据平台上的指针大小分配四到八个字节;在将其替换为
    strlen()
    之前,请注意
    strlen()
    不会在字符串末尾为
    NUL
    字节留出空间;
    malloc(len+1)
    是为字符串分配内存的常用模式,每当我在调用中看不到
    +1
    时,我就会担心。)

    一些t
    static Nav_str Nav_IN_OUT;
    static hguid_ref Guid_IN_OUT;
    static HopControl Control_IN_OUT;