2017-09-16 99 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

我明白我的錯誤。謝謝你的幫助...非常感謝。 –