亲爱的各位议员,我对是否在正确的地方释放记忆感到困惑.特别是*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;
}
Run Code Online (Sandbox Code Playgroud)
小智 7
你有没有研究过检测内存泄漏的工具,比如Valgrind?(Windows替代品)
在代码上运行这些代码将向您显示您泄漏的内存量,并且可能在哪里.
这不是一个完整的程序,所以我们无法为您传递它.一些忠告:
编辑:我将扩展它.为了让您了解内存泄漏何时发生,请考虑以下事项:
#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;
}
Run Code Online (Sandbox Code Playgroud)
这个程序非常简单地在堆上分配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
Run Code Online (Sandbox Code Playgroud)
为什么?因为你没有delete分配的内存new.粗略地说,这很复杂.
我说复杂,因为程序变得很快,内存泄漏突然变得更加复杂.谁分配了内存?谁释放了它?内存是作为库的一部分分配的吗?开始使用数组时会发生什么?通过释放阵列的外部级别而不是内部级别,可能会导致间接内存丢失.请参阅间接记忆丧失.
这很快变得非常复杂,特别是当函数开始分配内存并开始在别处使用它们时,您开始依赖于编程确定的内存大小,例如基于用户输入的字符串长度.该maxlen+1错误是常见的错误,可以在数据的较大二维数组做出巨大的泄漏.
根据您的新问题修改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
Run Code Online (Sandbox Code Playgroud)
如果你在函数调用中释放会发生什么?嗯,这实际上还不错,除了你可能会意外使用的代码范围内仍有一个变量.如果这样做,您将访问已明确发布的内存,这可能会导致程序崩溃.
我假设在某个阶段你想在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
Run Code Online (Sandbox Code Playgroud)
编辑4:只是为了澄清:
不要混合malloc/free和new/delete.如果你是malloc,释放那个内存,如果是新的,删除那个内存.如果你正在与C代码接口,除非它需要类似int的数组,你可以使用该string类型,不需要动态分配.除非你传递给C函数你无法控制,否则你应该考虑vector在数组之上.只有当你传递给C函数时,如果你需要进入C的malloc和free方法的世界,你就无法控制.