如何避免此代码中的内存泄漏?
How to avoid a memory leak in this code?
我有下一个代码,在按钮的点击事件中:
PNIO_DEV_ADDR addr;
addr.AddrType = PNIO_ADDR_GEO; //Para IO Device
addr.IODataType = PNIO_IO_OUT; //Escritura en PLC
addr.u.Geo.Slot = (int)(numericUpDownSlot->Value);
addr.u.Geo.Subslot = (int)(numericUpDownSubslot->Value);
CP1626::write(&addr);
PNIO_DEV_ADDR
是 C 结构,write
是链接到 DLL 回调的函数,它要求 PNIO_DEV_ADDR*
参数。
每次按下按钮时,我都可以在任务管理器中看到与我的应用关联的内存如何增加几个字节。
我用谷歌搜索并阅读了很多关于指针和参考的内容,但我不太明白我做错了什么。
你能解释一下问题出在哪里吗?
P.S.: 我正在使用 C 库(基于 DLL)和 C++/CLI 应用程序。
提前致谢。
编辑:
PNIO_DEV_ADDR
是:
typedef struct {
PNIO_ADDR_TYPE AddrType;
PNIO_IO_TYPE IODataType;
union {
PNIO_UINT32 Addr;
struct {
PNIO_UINT32 reserved1[2];
PNIO_UINT32 Slot;
PNIO_UINT32 Subslot;
PNIO_UINT32 reserved2;
} Geo; /* geographical address */
} u;
} ATTR_PACKED PNIO_DEV_ADDR;
当前两个变量是枚举时。
编辑 2:
这是DLL中函数write
的入口点:
PNIO_UINT32 write(PNIO_DEV_ADDR* addr){
PNIO_UINT32 result;
result = PNIOD_trigger_data_write_sync(g_devHndl, addr, PNIO_ACCESS_RT_WITH_LOCK);
return result;
}
PNIO_trigger_data_write_sync
需要 PNIO_DEV_ADDR*
。抱歉,我无法访问此函数内部,因为它位于第三方的不同 DLL 上。我应该复制 addr
指针吗?
C/C++
内存分配有两种,一种是编译时内存分配,一种是dynamic memory
(运行时内存分配)分配,我是你肯定知道这件事。编译期间的内存分配是从应用程序的 stack
完成的,dynamic
内存分配是从应用程序的 heap
完成的。我们需要关注从 heap
分配(动态)的内存释放以避免内存泄漏。对于从堆栈释放内存 compiler
自动管理它。
在您的情况下,分配是从 stack
完成的。因此一旦控件超出当前代码所在的方法范围,它会自动释放堆栈内存。
现在你的情况PNIO_DEV_ADDR addr;
,这是编译时内存分配,根本不是动态分配的内存。所以不会导致内存泄露。
在 dll
方法中,我确定它已将您的对象复制到其本地对象。
我有下一个代码,在按钮的点击事件中:
PNIO_DEV_ADDR addr;
addr.AddrType = PNIO_ADDR_GEO; //Para IO Device
addr.IODataType = PNIO_IO_OUT; //Escritura en PLC
addr.u.Geo.Slot = (int)(numericUpDownSlot->Value);
addr.u.Geo.Subslot = (int)(numericUpDownSubslot->Value);
CP1626::write(&addr);
PNIO_DEV_ADDR
是 C 结构,write
是链接到 DLL 回调的函数,它要求 PNIO_DEV_ADDR*
参数。
每次按下按钮时,我都可以在任务管理器中看到与我的应用关联的内存如何增加几个字节。
我用谷歌搜索并阅读了很多关于指针和参考的内容,但我不太明白我做错了什么。
你能解释一下问题出在哪里吗?
P.S.: 我正在使用 C 库(基于 DLL)和 C++/CLI 应用程序。
提前致谢。
编辑:
PNIO_DEV_ADDR
是:
typedef struct {
PNIO_ADDR_TYPE AddrType;
PNIO_IO_TYPE IODataType;
union {
PNIO_UINT32 Addr;
struct {
PNIO_UINT32 reserved1[2];
PNIO_UINT32 Slot;
PNIO_UINT32 Subslot;
PNIO_UINT32 reserved2;
} Geo; /* geographical address */
} u;
} ATTR_PACKED PNIO_DEV_ADDR;
当前两个变量是枚举时。
编辑 2:
这是DLL中函数write
的入口点:
PNIO_UINT32 write(PNIO_DEV_ADDR* addr){
PNIO_UINT32 result;
result = PNIOD_trigger_data_write_sync(g_devHndl, addr, PNIO_ACCESS_RT_WITH_LOCK);
return result;
}
PNIO_trigger_data_write_sync
需要 PNIO_DEV_ADDR*
。抱歉,我无法访问此函数内部,因为它位于第三方的不同 DLL 上。我应该复制 addr
指针吗?
C/C++
内存分配有两种,一种是编译时内存分配,一种是dynamic memory
(运行时内存分配)分配,我是你肯定知道这件事。编译期间的内存分配是从应用程序的 stack
完成的,dynamic
内存分配是从应用程序的 heap
完成的。我们需要关注从 heap
分配(动态)的内存释放以避免内存泄漏。对于从堆栈释放内存 compiler
自动管理它。
在您的情况下,分配是从 stack
完成的。因此一旦控件超出当前代码所在的方法范围,它会自动释放堆栈内存。
现在你的情况PNIO_DEV_ADDR addr;
,这是编译时内存分配,根本不是动态分配的内存。所以不会导致内存泄露。
在 dll
方法中,我确定它已将您的对象复制到其本地对象。