C++ 函数上的动态内存新字符[size]与字符[size]
所以我有一个函数,它有一个带有预定义缓冲区的字符串(缓冲区是在调用函数时定义的) 我的问题是,为什么每当我执行以下操作时(没有新的运算符?),编译器不抛出一个错误: 这不是正确的方法吗C++ 函数上的动态内存新字符[size]与字符[size],c++,new-operator,dynamic-memory-allocation,C++,New Operator,Dynamic Memory Allocation,所以我有一个函数,它有一个带有预定义缓冲区的字符串(缓冲区是在调用函数时定义的) 我的问题是,为什么每当我执行以下操作时(没有新的运算符?),编译器不抛出一个错误: 这不是正确的方法吗 int crc32test(unsigned char *write_string, int buffer_size){ // Append CRC32 to string int CRC_NBYTES = 4; int new_buffer_size = buffer_size
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;
}
实际上,我编译了这两个,而且都很有效。为什么编译器没有给我任何错误?
如果前一个函数显然也起作用,那么是否有理由使用新的运算符?第一个代码的格式不正确,但是一些编译器默认为接受非标准扩展的模式 您应该能够为标准一致性指定编译器开关。例如,在gcc中,
-std=c++17-pedantic
第二个代码是“正确的”,虽然也不是首选的方法,但您应该使用一个容器,在执行离开作用域时释放内存,而不是手动删除。例如,
std::vector buf(新的缓冲区大小+1)代码> 第一个代码的格式不正确,但是一些编译器默认为接受非标准扩展的模式
您应该能够为标准一致性指定编译器开关。例如,在gcc中,-std=c++17-pedantic
第二个代码是“正确的”,虽然也不是首选的方法,但您应该使用一个容器,在执行离开作用域时释放内存,而不是手动删除。例如,std::vector buf(新的缓冲区大小+1)代码> >第一个例子使用了C99特性,称为可变长度数组(VLA),默认情况下G+默认为C++语言扩展。这是非标准代码
代替第二个示例和类似的,你最好使用<代码> STD::vector < /代码> .< /P> < P>第一个例子使用了一个叫做可变长度数组(VLA)的C99特性,例如默认情况下G+默认为C++语言扩展。这是非标准代码
与第二个示例和类似示例不同,您最好使用std::vector
这里已经有了一些答案,我将重复已经说过的几句话。您使用的第一个窗体不是有效的C++,但将在GCC和CLang的某些版本中工作。它是绝对不可携带的
您有几个备选方案:
- 使用
std::string
输入和s.append(reinterpret_cast(crc),4)代码>
- 同样,您可以使用
std::vector
- 如果您只需要一个简单的可调整大小的缓冲区,您可以使用
std::unique\u ptr
和memcpy
&std::swap
等将数据移动到调整大小的缓冲区中,然后释放旧的缓冲区
- 作为临时缓冲区创建的非可移植替代方法,
alloca()
函数通过旋转堆栈指针来划分缓冲区。它不能很好地发挥C++的特性,但是如果非常小心地确保函数不会从它中抛出异常,它就可以使用。
- 将CRC与缓冲区一起存储在如下结构中
struct input {
std::unique_ptr<unsigned char[]> buffer;
uint32_t crc;
}
struct输入{
std::唯一的ptr缓冲区;
uint32_t crc;
}
并处理CRC和缓冲区在代码中其他地方的串联(即在输出时)。我相信这是最好的方法
这里已经有了一些答案,我将重复已经说过的几句话。您使用的第一个窗体不是有效的C++,但将在GCC和CLang的某些版本中工作。它是绝对不可携带的
您有几个备选方案:
- 使用
std::string
输入和s.append(reinterpret_cast(crc),4)代码>
- 同样,您可以使用
std::vector
- 如果您只需要一个简单的可调整大小的缓冲区,您可以使用
std::unique\u ptr
和memcpy
&std::swap
等将数据移动到调整大小的缓冲区中,然后释放旧的缓冲区
- 作为临时缓冲区创建的非可移植替代方法,
alloca()
函数通过旋转堆栈指针来划分缓冲区。它不能很好地发挥C++的特性,但是如果非常小心地确保函数不会从它中抛出异常,它就可以使用。
- 将CRC与缓冲区一起存储在如下结构中
struct input {
std::unique_ptr<unsigned char[]> buffer;
uint32_t crc;
}
struct输入{
std::唯一的ptr缓冲区;
uint32_t crc;
}
并处理CRC和缓冲区在代码中其他地方的串联(即在输出时)。我相信这是最好的方法
第一个(使用<代码>未签名的char AppDeldCcSt[NexBuffryStsie] < /Cord>)不是有效的C++。但是,某些编译器支持将其作为非标准扩展。您正在堆栈上分配..新运算符在堆栈上分配heap@setia_这与问题无关。请注意,此代码存在潜在的安全漏洞,如果<代码>缓冲区大小在 ItxMax < /C>中的4以内,则存在整数溢出导致未定义行为。第一个块创建了C可变长度数组(VLA),而不是C++标准的一部分。像GNU G++这样的编译器支持它作为扩展,但它不是可移植的。第一个(使用<代码>未签名的char AppDeNdCCRSHIGRITY [NeXuBuffRyStsix] )不是有效的C++。但是,某些编译器支持将其作为非标准扩展。您正在堆栈上分配..新运算符在堆栈上分配heap@setia_这与问题无关。请注意,此代码存在潜在的安全漏洞,如果<代码>缓冲区大小在 ItxMax < /C>中的4以内,则存在整数溢出导致未定义行为。第一个块创建了C可变长度数组(VLA),而不是C++标准的一部分。GNUG++等编译器支持将其作为扩展,但它不可移植。