gpt4 book ai didi

c++ - 为什么重载new运算符最后一个sr5对象不占内存?

转载 作者:太空宇宙 更新时间:2023-11-04 12:56:38 24 4
gpt4 key购买 nike

当我运行这个程序时 sr1 , sr2 , sr3 , sr4创建对象并将值分配给相应的变量。但是在sr5对象,name roll_no 时保持空白百分比显示正确的值。

改变值时

int MAX = 5;

int MAX = 6;

一切正常。

这是我的代码:

const int MAX = 5;
const int FREE = 0;
const int OCCUPIED = 1;
int flag = 0;
using namespace std;

void warning()
{
cout<<"\n------All memory occupied------"<<endl;
exit(1);
}

class student_rec
{
private:

char name[25];
int roll_no;
float percentage;

public:

student_rec(char *n, int r, float per)
{
strcpy(name, n);
roll_no = r;
percentage = per;
}
student_rec()
{
}

void set_rec(char *n, int r, float per)
{
strcpy(name, n);
roll_no = r;
percentage = per;
}

void show_rec()
{
cout<<"\n-------------------\n";
cout<<"Name= "<<name<<endl;
cout<<"Roll number= "<<roll_no<<endl;
cout<<"Percentage= "<<percentage<<endl;
}

void *operator new (size_t sz);
void operator delete (void *d);

};

struct memory_store
{
student_rec obj;
int status;
};
memory_store *m = NULL;

void *student_rec::operator new (size_t sz)
{
int i;

if(flag == 0)
{
m = (memory_store *) malloc(sz * MAX);
if(m == NULL)
warning();

for(i=0; i<MAX; i++)
m[i].status = FREE;

flag = 1;
m[0].status = OCCUPIED;
return &m[0].obj;
}

else
{
for(i=0; i<MAX; i++)
{
if(m[i].status == FREE)
{
m[i].status = OCCUPIED;
return &m[i].obj;
}
}
warning();
}

}

void student_rec::operator delete (void *d)
{
if(d == NULL)
return;

for(int i=0; i<MAX; i++)
{
if(d == &m[i].obj)
{
m[i].status = FREE;
strcpy(m[i].obj.name, "");
m[i].obj.roll_no = 0;
m[i].obj.percentage = 0.0;
}
}
}

int main()
{
student_rec *sr1, *sr2, *sr3, *sr4, *sr5, *sr6, *sr7;

sr1 = new student_rec("sandeep", 21, 78);
sr1->show_rec();

sr2 = new student_rec("sachin", 21, 78);
sr2->show_rec();

sr3 = new student_rec("sapna", 21, 78);
sr3->show_rec();

sr4 = new student_rec("vipin", 21, 78);
sr4->show_rec();

sr5 = new student_rec("niraj", 21, 78);
sr5->show_rec();

sr6 = new student_rec; // error all memory occupied.
return 0;
}

我在 linux 机器上运行这段代码。

最佳答案

这是糟糕的代码。它完全不知道 C++ 对象模型。忘掉它,从一本很好的介绍性书籍开始,它解释了对象的生命周期,以及如何正确地创建新对象。

关于问题的更多解释:缺陷 1

问题出在student_rec::operator new ()。这一行:

    m = (memory_store *) malloc(sz * MAX);

让您认为 m 指向某个有效的 memory_store 对象数组。不幸的是,C malloc() 用于分配原始内存。因此,该内存中没有有效的对象。换句话说,m 指向的对象处于未知的脏状态。

稍后,行

       m[i].status = FREE;

处理 m 指向的对象,就好像它们已经有效一样。这是未定义的行为。如果您不以 C++ 方式分配对象(例如 new 而不是 malloc() ),您首先需要使用 placement new 创建它们.

现在对于你的简单对象 trivial object 这不会造成太大的损害。还有另一个缺陷。

关于问题的更多解释:致命缺陷 2

还有第二个严重的问题:malloc 只分配了sz * MAX 字节。由于运算符为 student_rec 重载,因此将调用 szsizeof(student_rec)。但是你的代码假定它是 sizeof(memory_store),所以分配的内存至少是 sizeof(int)*n 字节太短了!!

这就是为什么增加 MAX(并因此分配比 5 个对象所需更多的内存)似乎有效的原因。

其他备注

像您那样使用全局变量,将 m 暴露给外界,是非常危险且容易出错的。假设在其他一些函数中你想使用一个局部变量m,但是忘记声明它;您破坏数据结构的速度可能比您预期的要快得多!您最好将其设为 student_rec 的私有(private)静态成员。

忘记用于存储 C 字符串的固定字符数组。如果名称比预期的要长,您会遇到另一个难以发现的严重问题(strcpy 在这种情况下可能会导致内存损坏)。如果您使用 C++ 编写代码,请利用 string 以免担心此类细节:-)

文体评论:为什么不将 flag 设为 bool 值并使用 true & false 而不是 0 和 1 ?

风格评论:warning() 函数有一个误导性的名称:warning() 建议您发出警告并继续。为什么不给它一个 self 记录的名称,例如 fatal_error()warning_and_exit()

关于c++ - 为什么重载new运算符最后一个sr5对象不占内存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46256459/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com