释放C库中的静态结构
我正在从事的一个项目涉及一个飞行器,其GNC代码写在C库(.out)中。我们必须以.out库的形式从LabVIEW(主要航空电子软件)调用此C代码,并且该软件的性质要求在连续调用函数之间使用静态指针存储数据。我们在整个飞行过程中定期调用GNC执行函数。我现在尝试在Windows上的DLL中使用Matlab MEX包装器调用此函数,这发现了一些内存管理问题 我在函数开头声明如下结构:释放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
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),但运气不好,所以如果有任何评论或建议,我将不胜感激。如果无法释放内存,不会导致分段错误。很可能你的问题出在别的地方。两种可能的情况是:
我的理解是这段记忆 应该把自己清理干净,是吗 这不对吗 是的,您需要调用
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;