将函数存储的返回值存入指向char变量的指针是正确的吗?

时间:2011-01-19 16:49:40

标签: c++ c

我写了一个读取函数,它从串口(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

4 个答案:

答案 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);
}

更新有关您的代码的一些注意事项

  1. int iMax = buffer+buffer_size-bufptr; - iMax将始终为1024;
  2. 我认为没有使用bufptr的任何想法,因为它的值与buffer相同,并且您不会在函数的任何位置更改它;
  3. iIn = read( fd, bufptr, buffer_size-1 );
  4. 您可以将bufptr[(int)iIn<iMax?iIn:iMax] = '\0';替换为bufptr[iIn] = '\0';
  5. if(bufptr != buffer)始终为false,这就是您的指针不正确并且始终返回0的原因;
  6. 如果errno == EAGAIN为真,请不要忘记释放缓冲区。目前您只返回0而没有free(buffer)
  7. 祝你好运;)

答案 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。它使代码的可读性降低。