38 votes

C ++: nouvel appel qui se comporte comme calloc?

Y a-t-il un appel que je peux passer à new pour que la mémoire soit nulle comme calloc ?

74voto

Johannes Schaub - litb Points 256113

Contrairement à ce que certains disent, dans leurs réponses, il est possible.

char * c = new char[N]();

Va zéro initialiser tous les personnages (en réalité, il est appelé valeur d'initialisation. Mais la valeur d'initialisation va être zéro-initialisation pour tous ses membres d'un tableau de type scalaire). Si c'est ce que vous êtes après.

Vaut la peine de noter qu'il ne travaillons aussi pour des (ensembles de) classe-types sans utilisateur déclaré constructeur dans ce cas, les membres de leur valeur est initialisée:

struct T { int a; };
T *t = new T[1]();
assert(t[0].a == 0);
delete[] t;

Ce n'est pas une extension, ou de quelque chose. Il a travaillé et s'est comporté de la même façon en C++98 trop. Juste là, il a été appelé d'initialisation par défaut au lieu de la valeur d'initialisation. Zéro initialisation, cependant, se fait dans les deux cas pour des scalaires ou des tableaux de scalaires ou POD types.

11voto

JaredPar Points 333733

Non, mais il est assez facile de créer une nouvelle version qui fonctionne comme calloc. Cela peut être fait de la même manière que la version sans lancement de new est implémentée.

SomeFile.h

 struct zeromemory_t{};
extern const zeromemory_t zeromemory;
void* __cdcel operator new(size_t cbSize, const zeromemory_t&);
 

SomeFile.cpp

 const zeromemory_t zeromemory;

void* _cdecl operator new(size_t cbSize, const zeromemory_t&)
{
    void *mem = ::operator new(cbSize);
    memset(mem,0,cbSize);
    return mem;
}
 

Vous pouvez maintenant effectuer les opérations suivantes pour obtenir de nouveaux éléments avec une mémoire nulle

 MyType* pMyType = new (zeromemory) MyType();
 

De plus, vous auriez besoin de faire d'autres choses amusantes comme définir de nouveaux [] qui est assez simple aussi.

4voto

Pablo Santa Cruz Points 73944

Non. Ne pensez même pas à faire quelque chose comme:

 YourClass *var = new YourClass;
memset(var, 0, sizeof(YourClass));
 

Vous pourriez finir par jeter votre VTABLE (si votre classe en a un).

Je recommanderais d'utiliser des constructeurs pour effacer la mémoire interne (variables) de votre classe.

2voto

Promit Points 2739

Nan. Il initialisera toujours par défaut les éléments alloués, ce qui, dans le cas des primitives, ne fait rien. Vous devrez le suivre avec un appel std :: uninitialized_fill_n ou similaire.

2voto

Michael Burr Points 181287

Vous pourriez faire un mondial de la surcharge de l'opérateur new et ont, prenez la mémoire brute d' calloc(). De cette façon, la mémoire est essuyée avant constructeurs arriver à courir, donc il n'y a pas de problèmes là-bas.

Toute classe qui remplace de nouveau sur son propre ne sera pas obtenir votre spécial calloc()base new, mais alors que la classe doit être initialisé correctement de toute façon.

N'oubliez pas de remplacer les deux new et delete et le tableau des versions...

Quelque chose comme:

#include <exception> // for std::bad_alloc
#include <new>
#include <stdlib.h> // for calloc() and free()

void* operator new (size_t size)
{
 void *p=calloc(size, 1); 
 if (p==0) // did allocation succeed?
  throw std::bad_alloc(); 
 return p;
}


void operator delete (void *p)
{
 free(p); 
}

void* operator new[] (size_t size)
{
 void *p=calloc(size, 1); 
 if (p==0) // did allocation succeed?
  throw std::bad_alloc();
 return p;
}

void operator delete[] (void *p)
{
 free(p); 
}

Notez que ces versions ne sont pas tout à fait exactement ce qu'elles devraient être - l' new opérateur doit exécuter dans une boucle de l'appel de la new_handler (s'il est installé) et seulement jeter l' bad_alloc exception si il n'y a pas d' new_handler. Ou quelque chose comme ça, je vais avoir à le rechercher et de mettre à jour plus tard.

Oh, et vous pouvez aussi remplacer l' no_throw version.

Prograide.com

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.

Powered by:

X