我写了一个读取函数,它从串口(LINUX)读取值。它返回值作为char的指针。我在另一个函数中调用此函数并将其再次存储在变量中作为指向char的指针。我偶尔会遇到堆栈溢出问题而不确定这个函数是否会产生问题。 样品如下。请提出一些建议或批评。
char *ReadToSerialPort( )
{
const int buffer_size = 1024;
char *buffer = (char *)malloc(buffer_size);
char *bufptr = buffer;
size_t iIn;
int iMax = buffer+buffer_size-bufptr;
if ( fd < 1 )
{
printf( "port is not open\n" );
// return -1;
}
iIn = read( fd, bufptr, 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
{
// *bufptr = '\0';
bufptr[(int)iIn<iMax?iIn:iMax] = '\0';
if(bufptr != buffer)
return bufptr;
}
free(buffer);
return 0;
} // end ReadAdrPort
int ParseFunction(void)
{
// some other code
char *sResult;
if( ( sResult = ReadToSerialPort()) >= 0)
{
printf("Response is %s\n", sResult);
// code to store char in string and put into db .
}
}
谢谢和问候, SamPrat
答案 0 :(得分:4)
您不释放缓冲区。完成工作后,您需要free
。
char * getData()
{
char *buf = (char *)malloc(255);
// Fill buffer
return buf;
}
void anotherFunc()
{
char *data = getData();
// Process data
free(data);
}
在你的情况下,我认为你应该在printf
之后释放缓冲区:
if( ( sResult = ReadToSerialPort()) >= 0)
{
printf("Response is %s\n", sResult);
// code to store char in string and put into db .
free(sResult);
}
更新静态缓冲区
使用静态缓冲区的另一种选择。它可以稍微提高性能,但getData
方法不是线程安全的。
char buff[1024];
char *getData()
{
// Write data to buff
return buff;
}
int main()
{
char *data = getData();
printf("%s", data);
}
更新有关您的代码的一些注意事项
int iMax = buffer+buffer_size-bufptr;
- iMax将始终为1024; bufptr
的任何想法,因为它的值与buffer
相同,并且您不会在函数的任何位置更改它; iIn = read( fd, bufptr, buffer_size-1 );
bufptr[(int)iIn<iMax?iIn:iMax] = '\0';
替换为bufptr[iIn] = '\0'
; if(bufptr != buffer)
始终为false
,这就是您的指针不正确并且始终返回0的原因; errno == EAGAIN
为真,请不要忘记释放缓冲区。目前您只返回0而没有free(buffer)
。答案 1 :(得分:1)
Elalfer部分正确。你可以自由()你的缓冲区,但不是在每种情况下。
例如,当您到达if ( errno == EAGAIN )
并且评估为true时,您return
没有在缓冲区上执行free
。
最好的方法是将缓冲区作为参数传递,并明确表示用户必须在函数外部释放缓冲区。 (在他编辑的答案中,这基本上就是Elalfer sais。)
刚才意识到这是一个C问题,我责备过滤这个:对不起!忽略以下内容,我将其留下,以便评论仍然有意义。
正确的解决方案应该使用std::vector<char>
,这样析构函数会在范围结束时为您处理内存释放。
答案 2 :(得分:0)
第二个指针的目的是什么?
char *buffer = (char *)malloc(buffer_size);
char *bufptr = buffer;
这是什么目的?
int iMax = buffer+buffer_size-bufptr; // eh?
这是为了什么目的?
bufptr[(int)iIn<iMax?iIn:iMax] = '\0'; // so you pass in 1023 (iMax - 1), it reads 1023, you've effectively corrupted the last byte.
我会重新开始,考虑使用std::vector<char>
,例如:
std::vector<char> buffer(1500); // default constructs 1500 chars
int iRead = read(fd, &buffer[0], 1500);
// resize the buffer if valid
if (iRead > 0)
buffer.resize(iRead); // this logically trims the buffer so that the iterators begin/end are correct.
return buffer;
然后在你的调用函数中,使用vector<char>
,如果你需要一个字符串,请构造一个:std::string foo(vect.begin(), vect.end());
等。
答案 3 :(得分:0)
当你设置空终止符“bufptr [(int)iIn
bufptr [iMax] =&gt; bufptr [1024] =&gt;超出您的分配一个字节,因为数组从0开始。
同样在这种情况下“int iMax = buffer + buffer_size-bufptr;”可以重写为iMax = buffer_size。它使代码的可读性降低。