Правильное использование памяти с длиной динамического массива в C ++ - PullRequest
0 голосов
/ 07 декабря 2018

При создании динамических массивов будет ли следующий код считаться «правильным» с точки зрения использования памяти и производительности?Пожалуйста, объясните, почему / почему нет.

Моя функция getFifoData получает указатель на буфер приема и внутренне вычисляет, как долго сообщение основывается на текущем размере FIFO, используя getFifoThreshold.

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);

1 Ответ

0 голосов
/ 09 декабря 2018

Я не уверен, что вы подразумеваете под "правильным";Ваш код неверен, по крайней мере, в том смысле, который упоминает @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:

Почему массивы переменной длины не являются частью стандарта C ++?

Проблемы с кодом

Вот некоторые вопросы, которые я считаю, вам следует рассмотреть.

Запутанные имена

  • Функция readWrite() - она ​​читает?это пишет?это делает и то и другое?Кто знает.
  • Не обрезайте имена.Если вы хотите назвать буфер, назовите его my_buffer, а не my_buff.Точно так же, diagnostic_output не diagOutput.
  • Никаких импровизированных инициалов.Что такое tBuffer?Это тестовый буфер?A t буфер транзакций?A t буфер передачи?A t императивный буфер?
  • Не все знают, что означает RX.
  • getFifoData() - что он вообще делает?Является ли его параметр "FIFO"?Это не то, что говорит название параметра.И если это так - где эта информация, якобы, мы получаем?Нет ни буфера назначения, который передан для использования, ни контейнера, который возвращен.

Вероятность переполнения буфера / неверный доступ к памяти

  • Почему getFifoData() принимает буфер безтакже принимая его длину?
  • Еще лучше, почему он не может взять span?

Использование динамически распределенных буферов

И std::vector, и массив переменной длины являются динамически выделяемой памятью.У VLA есть свои проблемы (см. Ссылку выше), но что касается векторов - вы будете выполнять вызов выделения памяти при каждом вызове этой функции;и это может быть дорого, если его часто вызывают.

Ведение журнала

Печать на консоль или в файл идет медленно.Ну, во всяком случае, медленно - это все относительно.Теперь это происходит в операторе «если», но если вы настроили приложение для регистрации событий, вы будете платить эту цену за каждый звонок getFifoData().

Время!

Наконец, - если вы беспокоитесь о производительности, время выполнения вашей функции или сделайте это с помощью профилировщика .Тогда вы сможете увидеть, сколько времени это на самом деле занимает и является ли это проблемой.

...