亲爱的会员, 我是否在正确的位置释放内存让我感到困惑。 特别是* sResult?
int ReadToSerialPort( char *psResponse, int iMax)
{
size_t iIn;
if ( fd < 1 )
{
printf( "port is not open\n" );
return -1;
}
iIn = read( fd, psResponse, iMax-1 );
if ( iIn < 0 )
{
if ( errno == EAGAIN )
{
printf( "The errror in READ" );
return 0; // assume that command generated no response
}
else
printf( "read error %d %s\n", errno, strerror(errno) );
}
else
psResponse[(int)iIn<(int)iMax?iIn:iMax] = '\n';
return iIn;
} // end ReadAdrPort
int MultiQuery ()
{
// check database connectivity
// code to check DB
while (1)
{ //while start
// char *sResult = NULL;
char *sResult = (char *)malloc(4096);
// Reading from H/W
if ( ( ReadToSerialPort(sResult,4096) ) > 0 )
{
// code to trim read line and put into db....
printf(" before free is %s\n", sResult);
free(sResult);
sResult = NULL;
} // end ifReadToSerialPort >0
//*sResult = NULL;
} // while(1) ends;
fclose(errorlog);
fclose(errorlog2);
mysql_close(&mysql);
return 0;
}
答案 0 :(得分:7)
您是否研究过检测内存泄漏的工具,例如Valgrind? (Windows substitutes)
在代码上运行这些内容会向您显示您正在泄漏多少内存,很可能在哪里。
这不是一个完整的程序,所以我们无法为您传递它。一些建议:
编辑:我会扩展它。为了让您了解内存泄漏何时发生,请考虑以下事项:
#include <iostream>
using namespace std;
int main(int argc, char** argv)
{
int* arr = new int(5);
// delete arr; // <-- uncomment this to fix memalloc bug.
return 0;
}
这个程序非常简单地在堆上分配4个字节,然后退出而不整理那个内存。
Valgrind会告诉你:
HEAP SUMMARY:
==23008== in use at exit: 4 bytes in 1 blocks
==23008== total heap usage: 1 allocs, 0 frees, 4 bytes allocated
==23008==
==23008== LEAK SUMMARY:
==23008== definitely lost: 4 bytes in 1 blocks
==23008== indirectly lost: 0 bytes in 0 blocks
==23008== possibly lost: 0 bytes in 0 blocks
==23008== still reachable: 0 bytes in 0 blocks
==23008== suppressed: 0 bytes in 0 blocks
为什么呢?因为您没有delete
使用new
分配的内存。粗略地说,这很复杂。
我说它很复杂,因为程序很快变成大型代码库,内存泄漏突然变得更加复杂。谁分配了内存?谁释放了它?内存是作为库的一部分分配的吗?开始使用数组时会发生什么?通过释放阵列的外部级别而不是内部级别,可能会导致间接内存丢失。请参阅indirect memory loss。
这很快变得非常复杂,特别是当函数开始分配内存并开始在别处使用它们时,你开始依赖于编程确定的内存大小,例如基于用户输入的字符串长度。 maxlen+1
错误是常见错误,可能会在较大的2D数据阵列中造成巨大泄漏。
根据您的新问题编辑2:
首先,如果您使用的是C ++,我强烈建议您忘记malloc
。使用new
和delete
因为它们理解多态性和对象,而malloc
则不然。您的构造函数可能无法正确调用。如果您需要字符串,请使用string
类型。如果您需要数组,vector
通常会这样做。
其次,如果读取操作正常,则只释放内存。为什么?您仍然分配了内存,因此无论读取操作是否有效,您仍然需要释放内存。您还应检查内存是否确实已分配,否则您将因访问不应访问的内存而导致分段错误。
编辑三:
好的,根据您的评论,请考虑以下代码,我认为您提议:
char* buffer = (char*)malloc(4096*sizeof(char));
if ( ReadToSerialPort(buffer, ...) > 0 ) // you are proposing to free in this func call
{
// do stuff A
}
// do stuff B
// free(buffer); // <-- you should free buffer here
如果你在函数调用中释放会发生什么?嗯,这实际上还不错,除了你可能会意外使用的代码范围内仍有一个变量。如果你这样做,你将访问你明确发布的内存,这可能会导致你的程序崩溃。
我假设在某个阶段你想在A部分或B部分使用这个缓冲区。在这种情况下你需要分配内存。
至于只在if语句中释放,如果read函数不起作用,这是一个保证内存泄漏,因为该内存永远不会被释放。
这是你应该怎么做的:
//
// I maintain you should use a string here, or
// if you insist on char*, use new.
// and delete.
//
char* buffer = (char*)malloc(4096*sizeof(char));
if ( buffer == NULL )
{
// os refused the alloc.
cout << "Out of memory\n" << endl;
return 1;
}
if ( ReadToSerialPort(buffer, ...) > 0 ) // this call frees as well?
{
// do stuff A using buffer
}
// do stuff B using buffer
free(buffer); // <-- you should free buffer here
编辑4:只是为了澄清:
不要混用malloc / free和new / delete 。如果你是malloc,释放那个内存,如果是新的,删除那个内存。如果你正在与C代码接口,除非它需要类似int的数组,你可以使用string
类型,不需要动态分配。除非您传递给C函数而无法控制,否则您应该在数组上方考虑vector
。只有当你传递给C函数时,如果你需要进入C的malloc和free方法的世界,你就无法控制。
答案 1 :(得分:1)
快速使用Ctrl + F(因为你发布了太多不相关的代码),表明你分配的唯一内存是* sResult,并且在释放内存之前没有exit子句,所以是的。在略读这段代码之后,我会犹豫使用“你做得对”这句话,但你正在这样做。