2017-09-16 4 views
1

Lorsque j'exécute ce programme sr1, sr2, sr3, sr4 des objets sont créés et des valeurs sont affectées aux variables correspondantes. Mais dans l'objet sr5, le name reste vide tandis que le pourcentage roll_no indique la valeur correcte.Pourquoi le dernier objet sr5 n'occupe-t-il pas la mémoire avec un nouvel opérateur surchargé?

Lorsque changer la valeur de

int MAX = 5; 

à

int MAX = 6; 

tout fonctionne bien.

Voici mon code:

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; 
} 

Je lance ce code sur la machine linux.

Répondre

0

Ceci est un code terrible. Il est totalement ignorant du modèle d'objet C++. Oubliez-le et commencez par un bon livre d'introduction, qui explique le cycle de vie de l'objet, et comment créer correctement de nouveaux objets.

Plus d'explications sur ce qui va mal: défauts 1

Le problème est en student_rec::operator new(). Cette ligne:

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

vous permettent de penser que les points m à une série valide de memory_store objets. Malheureusement, le C malloc() est utilisé pour allouer de la mémoire brute. Il n'y a donc pas d'objets valides dans cette mémoire. Autrement dit, les objets pointés par m sont dans un état sale inconnu.

Plus tard, la ligne

 m[i].status = FREE; 

gère les objets pointés par m comme si elles étaient déjà en cours de validité. C'est un comportement indéfini. Si vous n'allouez pas d'objets en mode C++ (par exemple new au lieu de malloc()), vous devez d'abord les créer avec un placement new. Maintenant, pour votre objet simple objet trivial cela ne causera pas trop de dommages. Il y a encore un autre défaut.

explications encore plus sur ce qui va mal: erreur fatale 2

Il y a un deuxième problème grave: malloc allouent seulement sz * MAX octets. Comme l'opérateur est surchargé pour student_rec, il sera appelé avec sz étant sizeof(student_rec). Mais votre code suppose qu'il est sizeof(memory_store), de sorte que la mémoire allouée est au moins sizeof(int)*n octets trop court !!

C'est pourquoi augmenter MAX (et donc allouer plus de mémoire que nécessaire pour vos 5 objets) semble fonctionner.

Autres remarques

Utilisation des variables globales que vous avez fait, ce qui expose m au monde extérieur, est très dangereuse et sujette aux erreurs. Supposons que dans certaines autres fonctions, vous aimeriez utiliser une variable locale m, mais oubliez de la déclarer; vous pourriez corrompre votre structure de données beaucoup plus rapidement que prévu! Vous feriez mieux de faire un membre statique privé de student_rec. Oubliez les tableaux de caractères fixes pour stocker les chaînes de caractères C. Si un nom est plus long que prévu, vous aurez un autre problème sérieux qui est difficile à repérer (strcpy pourrait entraîner une corruption de la mémoire dans ce cas). Si vous le code en C++, profitez de string afin de ne pas se soucier des détails :-)

remarque Stylistic: pourquoi ne pas faire flag un booléen et utiliser true & false au lieu de 0 et 1? Remarque stylistique: La fonction warning() a un nom trompeur: warning() vous invite à émettre un avertissement et à continuer. Pourquoi ne pas lui donner un nom auto-documenté comme par exemple fatal_error() ou warning_and_exit()

+1

Je comprends mes erreurs. Merci pour votre aide ... Thanku beaucoup. –