函数上的动态内存new char [size] vs char [size]

时间:2018-05-13 01:18:19

标签: c++ new-operator dynamic-memory-allocation

所以我有这个函数有一个带有预定义缓冲区的字符串(缓冲区是在调用函数时定义的)。

我的问题是,为什么编译器在我执行以下操作时都会抛出错误(没有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 :(得分:2)

第一个代码格式不正确,但有些编译器默认采用非标准扩展的模式。

您应该能够为标准一致性指定编译器开关。例如,在gcc中,-std=c++17 -pedantic

第二个代码是“正确的”,虽然不是首选方法,但是你应该使用一个容器,当执行离开作用域时释放内存,而不是手动删除。例如,std::vector<unsigned char> buf(new_buffer_size + 1);

答案 1 :(得分:2)

这里已经有了一些答案,我将重复已经说过的几件事。您使用的第一个表单不是有效的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&amp; std::swap等将数据移动到已调整大小的缓冲区,然后释放旧缓冲区。
  • 作为临时缓冲区创建的非便携替代方法,alloca()函数通过调整堆栈指针来创建缓冲区。它不能很好地发挥C ++的功能,但如果非常小心确保函数永远不会抛出异常,就可以使用它。
  • 将CRC与缓冲区一起存储在

    这样的结构中
    struct input {
        std::unique_ptr<unsigned char[]> buffer;
        uint32_t crc;
    }
    

    处理代码中其他地方(即输出)的CRC和缓冲区的串联。我相信这是最好的方法。

答案 2 :(得分:0)

第一个示例使用称为可变长度数组(VLA)的C99功能,例如默认情况下,g ++支持作为C ++语言扩展。这是非标准代码。

最好使用std::vector

,而不是第二个示例和类似示例