2017-04-14 4 views
0

J'ai été chargé de corriger certains bogues possibles dans notre projet et j'ai constaté qu'un pointeur vide était en train d'être supprimé dans l'une des fonctions.Suppression d'un pointeur vide en C++

Je sais que vous n'êtes pas censé supprimer un pointeur vide et que vous devez le renvoyer à son type d'origine avant de le supprimer afin qu'il soit correctement détruit. Cependant, le code est le suivant:

void someFunction() { 
    void *a[2] = {NULL, NULL}; 
    initializeFunction(a+0); 
    initializeFunction(a+1); 
    ... 
    //do something 
    ... 
    delete a[0]; 
    delete a[1]; 
} 

initializeFunction(void** b) { 
    *b = new unsigned char [size]; //size is calculated based on all the types and how many of each are used in innerFunction() 
    innerFunction((char *)*b); 
} 

innerFunction(char * x) { 
    *((int *)x) = intValue; 
    *((double *)(x += sizeof(int))) = doubleValue; 
    *((SomeClass *)(x += sizeof(doubleValue))) = aSomeClassObject; 
    *((AnotherClass *)(x += sizeof(aSomeClassObject))) = anAnotherClassObject; 
} 

Je ne savais pas comment aborder cela car je n'ai jamais rencontré un tel usage. Je suis confus avec tous les moulages et la variété des types étant sauvés. Ce innerFunction avait plus de types dans le code réel. (Bien que peut-être il est intéressant de noter que, hormis les types de données primitifs, toutes les classes définies par l'utilisateur utilisé seulement avaient des variables membres du tableau.)

Pour supprimer a, est aussi simple que la coulée à (unsigned char*)? Ou cela ne fonctionne-t-il pas parce que techniquement il y a différents types dans la mémoire pointée par a? Devrai-je faire l'équivalent de suppression de innerFunction()?

+3

Ma recommandation: courir aussi vite que vous pouvez loin de ce code. Il y a un comportement indéfini partout. Si cela est indicatif de la qualité de la base de code, il est probable que cela dépasse le point de fixation. –

+0

Je pense que le programmeur pensait qu'il supprimait un tableau dynamique :) –

+0

@JasonR Je le ferais si je le pouvais. :(Il y a des plans pour refactoriser le code mais ça va être difficile ... – yushi

Répondre

1

Si possible, modifiez ce code pour utiliser un struct contenant tous les sous-objets nécessaires.

Si nous venons de vérifier que tous les types utilisés sont POD et supposons aveuglément qu'il n'y a pas de problèmes d'alignement et que le compilateur ne tombe pas dans des trappes strictes d'aliasing, alors oui, vous pouvez changer

delete[] static_cast<unsigned char*>(a[0]); 
delete[] static_cast<unsigned char*>(a[1]); 

et ont un comportement légèrement plus sûr.

0

Le problème avec la suppression des pointeurs vides est que les détracteurs ne sont pas appelés. Donc, si vous avez une fonction qui retourne un pointeur possédé, vous devriez avoir une fonction qui le détruit aussi.