当我运行此程序时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机器上运行此代码。
答案 0 :(得分:0)
这是可怕的代码。它完全没有意识到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创建对象。
现在对于你的简单对象琐碎的对象,这不会造成太多的伤害。还有另一个缺陷。
关于出了什么问题的更多解释:致命缺陷2
还有第二个严重问题:malloc
仅分配sz * MAX
个字节。由于student_rec
的运算符过载,将调用sz
为sizeof(student_rec)
的运算符。但是你的代码假设它是sizeof(memory_store)
,所以分配的内存至少sizeof(int)*n
个字节太短!!
这就是为什么增加MAX(从而分配比5个对象所需的更多内存)似乎有效。
其他评论
像你一样使用全局变量,将m
暴露给外界,是非常危险且容易出错的。假设在其他一些函数中你想使用局部变量m
,但忘记声明它;你可能会比你期望的更快地破坏你的数据结构!您最好将其设为student_rec
的私有静态成员。
忘记用于存储C字符串的固定字符数组。如果名称长于预期,则会出现另一个难以发现的严重问题(strcpy
可能会导致内存损坏)。如果您使用C ++编写代码,请利用string
以免担心此类细节: - )
文体评论:为什么不将flag
作为布尔值并使用true
&amp; false
而不是0和1?
文体评论:warning()
函数具有误导性名称:warning()
表示您发出警告并继续。为什么不给它一个自我记录的名称,例如fatal_error()
或warning_and_exit()