重载新返回错误的地址

时间:2017-07-25 12:33:21

标签: c++

#include <iostream>
using namespace std;

class station{
    int n;
    float *p;
public:
    station(){};
    station(const station &ob){cout<<"Copy";}
    station operator=(station* a){cout<<"Nai";}
    ~station(){cout<<"Destructor";}
    static float counter;
    friend istream &operator>(istream  &stream, station &d);
    int &getN(){return n;};
    float *&getP(){return p;};
    void* operator new[](size_t size);
    void* operator new(size_t size){station *a;a=::new station;return a;};


};
void* station::operator new[](size_t size){
    station* a;
    a=(::new station[size]);
    int b;
    b=(size)/(sizeof(station));
    for(int i=0;i<b;i++){
        cin>a[i];
    }
   cout<<a;
    return a;
}



float station::counter;
istream &operator>( istream  &stream, station &d){
    cout<<"Dwse arithmo deigmatwn";
    int num;
    stream>>num;
    d.getP()=new float[num];
    d.getN()=num;
    for(int i=0;i<num;i++){
        stream>>d.getP()[i];
    }
    return stream;
}



int main(){
    station* a;
    a=new station[2];
    cout<<a;
    return 0;
}

大家好, 这是我的第一篇文章,请原谅我的任何错误。

我创建了一个带有new运算符和提取器重载的新类。我的问题是new返回的地址与重载运算符内的地址不同,正如您在cout<<a所述的行中所看到的那样。但是,当我擦除析构函数时,一切正常。有什么想法吗?

1 个答案:

答案 0 :(得分:3)

当使用new[]运算符时,编译器可以为内部簿记分配一些额外的空间(以存储例如数组大小,因此在调用delete[]时,它将知道要销毁多少对象) 。这是您在“原始”分配和最终数组分配的对象地址之间看到的差异。

这也是为什么你不应该在通过delete分配的内存上调用new[]的原因,反之亦然,因为它可能导致内存泄漏(只有第一个对象被破坏),访问无效数据和/或释放坏指针(技术上称为所有UB)。

修改

对于对象内容问题,你不应该像这样初始化operator new[]中的对象

for(int i=0;i<b;i++){
    cin>a[i];
}

operator new / new []只是为了分配“原始”内存。

如果您愿意,只需删除它并读取构造函数中的对象(编译器会自动为编译器中的每个对象调用构造函数),例如:

station(){cin >> *this}; // or '>' if you really want to keep that

但一般来说,从流中读取通常是明确的,所以你可以这样做:

a=new station[2];
for(int i=0;i<2;i++){
    cin>a[i];
}
<{1>}中的