【问题标题】:Using the new operator in an object method在对象方法中使用 new 运算符
【发布时间】:2013-07-13 05:52:44
【问题描述】:

我对 C++ 还是很陌生。我正在将文件的内容读入如下结构:

struct wavObj {
    uint8_t *dataBuffer;        // the data   
    int readFile( const char *filePath );

};

int wavObj::readFile( const char *filePath ) {

    FILE *file = NULL;      // File pointer

    file = fopen( filePath, "rb" );

    dataBuffer = new uint8_t[data_Size];
    fread(dataBuffer, data_Size, 1, file);

    fclose(file);

    return 0;


}

我是否需要在某处使用删除运算符来删除 wavObj.dataBuffer?当程序结束时这个结构会被破坏吗,内存分配也会被破坏吗?如果没有,我可以制作一个使用删除运算符的析构函数吗?

【问题讨论】:

标签: c++ class struct new-operator delete-operator


【解决方案1】:

如 cmets 中所述,更好的方法是使用 std::vector<>

struct wavObj {
    std::vector<uint8_t> dataBuffer;        // the data   
    int readFile( const char *filePath );
};

int wavObj::readFile( const char *filePath ) {
    //...
    dataBuffer.clear();
    dataBuffer.resize(data_Size);
    fread(&dataBuffer[0], data_Size, 1, file);
    //...
}

这避免了定义析构函数、复制构造函数和赋值运算符(以及移动变体)的需要。这有时被称为Rule of Three(或Rule of Three-or-Four-or-Five):

如果您将dataBuffer 保留为接收动态分配的裸指针,那么您将需要添加更多代码以正确获取您确定的内存。大多数程序员都知道进行清理的一个地方是析构函数。

struct wavObj {
    uint8_t *dataBuffer;        // the data   
    int readFile( const char *filePath );
    ~wavObj () { delete [] dataBuffer; }
};

但是,三法则要求还定义复制构造函数以正确地从它正在复制的对象复制指针,并定义一个赋值运算符以正确清理本地副本并正确复制指针右手边。不这样做可能会导致由悬空指针引起的未定义行为。由于额外的复杂性,如果可能,最好完全避免该问题。

【讨论】:

    【解决方案2】:

    你应该显式声明一个析构函数来释放内存,否则可能导致溢出。

    当你的程序结束时,分配的内存不会被标记为空闲,也不会成为空闲内存池的一部分。您需要显式删除分配的内存。

    但是你也应该遵循三规则

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-17
      • 2012-03-22
      相关资源
      最近更新 更多