J'ai vérifié le code suivant en C ++ avec valgrind
avec --leak-check=full
et il ne dit aucune fuite de mémoire. Pourquoi donc?
char *p = new char[256];
delete p;
new[]
devrait être égalé par delete[]
pour autant que je sache.
J'ai vérifié le code suivant en C ++ avec valgrind
avec --leak-check=full
et il ne dit aucune fuite de mémoire. Pourquoi donc?
char *p = new char[256];
delete p;
new[]
devrait être égalé par delete[]
pour autant que je sache.
Même si c'est un comportement indéterminé comme @KillianDS dit, la différence probablement liés au fait que les deux delete
et delete[]
gratuit à la mémoire sous-jacente. Le point de delete[]
, c'est que les destructeurs pour chaque objet du tableau sont appelés avant que la mémoire est libérée. Depuis char
est un POD et ne pas avoir un destructeur, il n'est pas efficace, toute différence entre les deux dans ce cas.
Vous ne devriez pas compter sur elle, cependant.
delete
et delete[]
ne seront égaux que si p
pointe vers des types de données de base, tels que char ou int.
Si p
pointe vers un tableau d'objets, le résultat sera différent. Essayez le code ci-dessous:
class T {
public:
T() { cout << "constructor" << endl; }
~T() { cout << "destructor" << endl; }
};
int main()
{
const int NUM = 3;
T* p1 = new T[NUM];
cout << p1 << endl;
// delete[] p1;
delete p1;
T* p2 = new T[NUM];
cout << p2 << endl;
delete[] p2;
}
En utilisant delete[]
tous les destructeurs de T dans le tableau seront invoqués. En utilisant delete
seul le destructeur de p[0]
sera invoqué.
Lorsque j'essaie, Valgrind rapporte:
==22707== Mismatched free() / delete / delete []
==22707== at 0x4C2B59C: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==22707== by 0x40066D: main (in /home/andrew/stackoverflow/memtest)
==22707== Address 0x5a1a040 is 0 bytes inside a block of size 256 alloc'd
==22707== at 0x4C2C037: operator new[](unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==22707== by 0x40065D: main (in /home/andrew/stackoverflow/memtest)
Ce n'est pas vraiment une fuite de mémoire, mais valgrind remarque le problème.
C'est un comportement indéfini, donc nous ne pouvons pas raison au sujet de son comportement. Si l'on regarde le projet de norme C++ section 3.7.4.2
de Désallocation de fonctions, alinéa 3 dit: (c'est moi qui souligne):
[...] Sinon, le comportement est indéfini si la valeur fournie à l'opérateur delete(void*) dans la bibliothèque standard n'est pas l'une des valeurs retournées par un appel précédent de l'opérateur new(std::size_t) ou l'opérateur new(std::size_t, conststd::nothrow_t&) dans la bibliothèque standard, et le comportement est indéfini si la valeur fournie à l'opérateur delete[] (void*) dans la bibliothèque standard n'est pas l'une des valeurs retournées par un appel précédent de l'opérateur new[] (std::size_t) ou l'opérateur new[] (std::size_t, const std::nothrow_t&) dans le la bibliothèque standard.
Les détails réels vont être définis par l'implémentation de comportement et peut varier considérablement.
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.