所以我有这个函数有一个带有预定义缓冲区的字符串(缓冲区是在调用函数时定义的)。
我的问题是,为什么编译器在我执行以下操作时都会抛出错误(没有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运算符,如果显然前一个函数也有效?
答案 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
。