2017-09-16 56 views
1

当我运行这个程序sr1,sr2, sr3,sr4对象被创建并且值被分配给相应的变量。但在sr5对象中,name保持空白,而roll_no百分比显示正确的值。为什么最后一个sr5对象不会占用超载的新运算符的内存?

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

这是可怕的代码。它完全不了解C++对象模型。忘记它,并从一本很好的入门书开始,它解释了对象的生命周期,以及如何正确地创建新对象。

更多解释什么不顺心:缺陷1

问题出在student_rec::operator new()。这条线:

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

让你认为mmemory_store对象的一些有效的阵列。不幸的是,C malloc()被用来分配原始内存。因此在该内存中没有有效的对象。否则说,m指向的对象处于未知的脏状态。

后来,行

 m[i].status = FREE; 

处理由M指出,如果他们已经有效的对象。这是未定义的行为。如果您不用C++方式分配对象(例如new而不是malloc()),则首先需要使用placement new创建对象。

现在,您的简单对象不重要的对象,这不会造成太多的损害。还有另一个缺陷。

什么不顺心更解释:致命的缺陷2

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

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

其他说明

使用全局变量像你一样,露出m到外面的世界,是非常危险的,容易出错。假设在其他一些函数中,你想使用局部变量m,但忘记声明它;你可能会比预期的更快地破坏你的数据结构!你最好让它成为student_rec的私人静态成员。

忘记固定字符数组存储C字符串。如果一个名字比预期的要长,你会得到另一个很难发现的严重问题(在这种情况下,strcpy可能导致内存损坏)。如果您在C++代码,利用string为了不担心这些细节:-)

文体句话:为什么不把flag一个布尔值,并使用true & false而不是0和1?

文体备注:warning()函数有一个令人误解的名称:warning()建议您发出警告并继续。为什么不给它一个自我记录的名称,例如fatal_error()warning_and_exit()

+1

我明白我的错误。谢谢你的帮助...非常感谢。 –