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++等编译器支持将其作为扩展,但它不可移植。