Динамическая память на функции новый символ [размер] против символа [размер] - PullRequest
0 голосов
/ 13 мая 2018

Итак, у меня есть эта функция, в которой есть строка с предопределенным буфером (буфер определяется при вызове функции).

Мой вопрос: почему компилятор не выдает мне ошибку, когда я делаю следующее (без оператора new?):

int crc32test(unsigned char *write_string, int buffer_size){
     // Append CRC32 to string
     int CRC_NBYTES = 4;
     int new_buffer_size = buffer_size + CRC_NBYTES; // Current buffer size + CRC

     // HERE (DECLARATION OF THE STRING)
     unsigned char appendedcrc_string[new_buffer_size];

     return 0;

}

НЕ ЭТО правильный способ сделать это ..?

int crc32test(unsigned char *write_string, int buffer_size){
      // Append CRC32 to string
     int CRC_NBYTES = 4;
     int new_buffer_size = buffer_size + CRC_NBYTES; // Current buffer size + CRC

     // HERE (DECLARATION OF THE STRING USING NEW)
     unsigned char * appendedcrc_string = new unsigned char[new_buffer_size+1];


     delete[] appendedcrc_string ;

     return 0;

}

И я фактически скомпилировал оба, и оба сработали. Почему компилятор не выдаёт мне ошибку? И есть ли причина использовать оператор new, если очевидно, что предыдущая функция тоже работает?

Ответы [ 3 ]

0 голосов
/ 13 мая 2018

В первом примере используется функция C99, называемая массивами переменной длины (VLA), например, G ++ по умолчанию поддерживается как расширение языка C ++. Это нестандартный код.

Вместо второго примера и аналогичных, вы должны предпочтительно использовать std::vector.

0 голосов
/ 13 мая 2018

Здесь уже есть несколько ответов, и я собираюсь повторить уже сказанное. Первая используемая вами форма не является допустимой C ++, но будет работать в определенных версиях GCC и CLang ... Она определенно не переносима.

В качестве альтернативы у вас есть несколько вариантов:

  • Используйте std::string<unsigned char> для ввода и s.append(reinterpret_cast<unsigned char*>(crc), 4);
  • Точно так же вы можете использовать std::vector<unsigned char>
  • Если вам нужен только простой буфер с изменяемым размером, вы можете использовать std::unique_ptr<unsigned char[]> и memcpy & std::swap и т. Д., Чтобы переместить данные в буфер с измененным размером и затем освободить старый буфер.
  • В качестве непереносимой альтернативы для временного создания буфера, функция alloca() выделяет буфер, поворачивая указатель стека. Он не очень хорошо работает с функциями C ++, но его можно использовать, если крайне осторожно следить за тем, чтобы функция никогда не вызывала исключение.
  • Сохраните CRC с буфером в структуре, подобной

    struct input {
        std::unique_ptr<unsigned char[]> buffer;
        uint32_t crc;
    }
    

    И работать с конкатенацией CRC и буферизовать где-нибудь еще в вашем коде (т.е. при выводе). Это, я считаю, лучший метод.

0 голосов
/ 13 мая 2018

Первый код некорректен, однако некоторые компиляторы по умолчанию используют режим, в котором допускаются нестандартные расширения.

Вы должны быть в состоянии указать параметры компилятора для стандартного соответствия. Например, в gcc, -std=c++17 -pedantic.

Второй код является «правильным», хотя и не является предпочтительным способом, вы должны использовать контейнер, который освобождает память, когда выполнение выходит из области действия, вместо удаления вручную. Например, std::vector<unsigned char> buf(new_buffer_size + 1);.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...