在 C++ 中正确使用具有动态数组长度的内存

Proper use of memory with dynamic array lengths in c++

创建动态数组时,以下代码在内存使用和性能方面是否会被视为 "correct"?请解释为什么/为什么不。

我的函数 getFifoData 使用指向接收缓冲区的指针,并使用 getFifoThreshold 在内部根据当前 FIFO 大小计算消息的长度。

int serial_spi_handler::getFifoData(unsigned char * rxBuf) {
  uint16_t currentFifoThreshold = getFifoThreshold();
  const int msgLength = (currentFifoThreshold * 2) + 1;

  std::vector < uint8_t > txBuf;
  txBuf.reserve(msgLength);

  uint8_t tBuff[txBuf.size()];
  tBuff[0] = 0xC2;

  int bytesWritten = readWrite(busDescriptor, tBuff, rxBuf, msgLength);

  if (consoleLogging) {
    printf("getFifoData function, wrote: %d bytes\n\r", bytesWritten);
  } else if (diagOutput) {
    qDebug() << "getFifoData function, wrote: " << bytesWritten << " bytes";
  }
  return msgLength;
}

//Header of readWrite:

//int readWrite(int busDescriptor, uint8_t *pTxBuffer, uint8_t *pRxBuffer, int length);

我不确定你说的 "correct" 是什么意思;您的代码至少在@SamVarshavchik 提到的意义上是不正确的,编译器会告诉您:

a.cpp: In function ‘int getFifoData(unsigned char*)’:
a.cpp:20:29: warning: ISO C++ forbids variable length array ‘tBuff’ [-Wvla]
   uint8_t tBuff[txBuf.size()];

如果您想了解为什么 C++ 没有 VLA,请阅读这个 SO 问题:

Why aren't variable-length arrays part of the C++ standard?

代码有问题

以下是我认为您应该考虑的一些问题。

混淆名称

  • 函数readWrite() - 它读了吗?它写了吗?两者都有吗?谁知道呢
  • 不要剪辑名字。如果要命名缓冲区,请将其命名为 my_buffer,而不是 my_buff。同样,diagnostic_output 而不是 diagOutput
  • 没有即兴的缩写。什么是 tBuffer?它是测试缓冲区吗? t交易缓冲区? t传输缓冲区? t临时缓冲区?
  • 不是每个人都知道 RX 是什么意思。
  • getFifoData() - 它有什么作用?它的参数是"FIFO"吗?这不是参数名称所说的。如果是的话——我们应该从哪里得到这些信息?没有传递给使用的目标缓冲区,也没有返回的容器。

缓冲区溢出/无效内存访问的可能性

  • 为什么 getFifoData() 获取缓冲区而不同时获取其长度?
  • 更好的是,为什么不能

动态分配缓冲区的使用

std::vector和变长数组都是动态分配的内存。 VLA 有它们自己的问题(请参阅上面的 link),但对于向量 - 您将在每次调用此函数时执行内存分配调用;如果它被调用很多,那可能会很昂贵。

日志记录

打印到控制台或文件的速度很慢。好吧,无论如何,有点慢——这都是相对的。现在,这发生在 "if" 语句中,但如果您已将应用配置为记录内容,则每次调用 getFifoData().

时都将支付此费用

计时!

最后,- 如果您担心性能,time your function, or do it with a profiler。然后你可以看到它实际花费了多少时间以及这是否是一个问题。