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

Dynamic memory on a function new char[size] vs char[size]

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

我的问题是,为什么每当我执行以下操作(没有 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 运算符?

第一个代码格式错误,但是某些编译器默认采用接受非标准扩展的模式。

您应该能够指定编译器开关以符合标准。例如,在 gcc 中,-std=c++17 -pedantic.

第二个代码是"correct",虽然也不是首选方法,但您应该使用一个容器,在执行离开范围时释放内存,而不是手动删除。例如,std::vector<unsigned char> buf(new_buffer_size + 1);

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

而不是第二个例子和类似的,你应该最好使用 std::vector

这里已经有一些答案了,我要重复已经说过的几件事。您使用的第一种形式不是有效的 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 的串联并在代码中的其他位置(即输出)进行缓冲。这个,我认为是最好的方法。