函数 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 的串联并在代码中的其他位置(即输出)进行缓冲。这个,我认为是最好的方法。
所以我有这个函数,它有一个带有预定义缓冲区的字符串(缓冲区是在调用函数时定义的)。
我的问题是,为什么每当我执行以下操作(没有 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 的串联并在代码中的其他位置(即输出)进行缓冲。这个,我认为是最好的方法。