Question

Existe-t-il un appel que je peux passer à new pour le mettre à zéro comme calloc?

Était-ce utile?

La solution

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

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

Initialisera tous les caractères à zéro (en réalité, cela s'appelle l'initialisation de la valeur. Mais l'initialisation de la valeur sera une initialisation à zéro pour tous ses membres d'un tableau de type scalaire). Si c'est ce que vous recherchez.

Il est intéressant de noter que cela fonctionne également pour les (tableaux de) classes-types sans constructeur déclaré par l'utilisateur, auquel cas l'un de leurs membres est initialisé en valeur:

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

Ce n'est pas une extension ou quelque chose. Cela fonctionnait et se comportait de la même manière en C ++ 98 également. Juste là, cela s’appelait initialisation par défaut au lieu d’initialisation de valeur. Toutefois, l'initialisation à zéro est effectuée dans les deux cas pour les scalaires ou les tableaux de types scalaires ou POD.

Autres conseils

Non, mais il est assez facile de créer une nouvelle version qui se comporte comme un calloc. Cela peut être fait de la même manière que la version sans rejet de new est mise en œuvre.

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

Maintenant, vous pouvez faire ce qui suit pour en obtenir de nouveaux sans mémoire

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

De plus, vous aurez besoin de faire d’autres choses amusantes, comme définir un nouveau [] qui est également assez simple.

Non. Aussi, ne pensez même pas à faire quelque chose comme:

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

Vous pourriez finir par détruire votre VTABLE (si votre classe en a un).

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

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

Vous pouvez créer une surcharge globale de l'opérateur new et lui demander de récupérer la mémoire brute de calloc(). De cette façon, la mémoire est effacée avant que les constructeurs ne s'exécutent, il n'y a donc aucun problème.

Toute classe qui substitue neuve par elle-même n’aura pas votre spécial delete - new_handler, mais cette classe devrait s’initialiser correctement de toute façon.

N'oubliez pas de remplacer les versions bad_alloc et no_throw ainsi que celles du tableau ...

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 simples ne sont pas exactement ce qu'elles devraient être - l'opérateur <=> doit s'exécuter en boucle en appelant <=> (s'il en existe un) et en ne lançant l'exception <=> que s'il existe non <=>. Ou quelque chose comme ça, je vais devoir regarder et mettre à jour plus tard.

Oh, et vous voudrez peut-être également remplacer la <=> version.

j'utilise une macro:

#define newclear(TYPE) new(calloc(sizeof(TYPE), 1)) TYPE();

pour l'utiliser:

Whatever* myWhatever = newclear(Whatever);

(cela utilise & "placement new &"; comme d'autres solutions ici)

Non. Vous devez mettre à zéro manuellement la mémoire en sortie. N'oubliez pas que new ne concerne pas seulement l'allocation de mémoire, mais également l'initialisation via des constructeurs. C’est là que calloc est utile en C (qui n’a pas de fonction d’initialisation). Vous êtes libre d'écrire un wrapper sur <=> ou même d'utiliser <=>, mais la plupart du temps pour des objets autres que POD, cela n'a pas beaucoup de sens.

si vous n'insistez pas pour utiliser new, vous pouvez simplement utiliser le vecteur: vector<char> buffer; buffer.resize(newsize); et le contenu sera mis à zéro.

class MyClass {
    public:
    void* operator new(size_t bytes) {
        return calloc(bytes, 1);
    }
}

Et vous pouvez remplacer le nouvel opérateur global si vous le souhaitez.

Vous pouvez dire:

vector <char> v( 100, 0 );

qui crée un tableau contigu de 100 caractères en utilisant new et les initialise à zéro. Vous pouvez ensuite accéder au tableau avec l'opérateur [] de vector ou en faisant:

char * p = &v[0];
p[3] = 42;

Notez que cela vous évite également d'appeler delete pour libérer la mémoire allouée.

Oui.

int* p_scalar = new int(5);//Does not create 5 elements, but initializes to 5

Pour les tableaux, vous pouvez utiliser quelque chose comme memset. Pour Windows, utilisez ZeroMemory ou SecureZeroMemory.

Éditer: Veuillez lire le post de @ litb, il montre comment initialiser à 0 pour les tableaux utilisant une initialisation non directe comme ci-dessus.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top