Frage

Ist es ein Anruf, den ich machen kann, um new es haben null-Speicher wie calloc?

War es hilfreich?

Lösung

Entgegen dem, was einige sagen in Ihren Antworten, es ist möglich.

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

Wird null initialisiert alle Zeichen (in der Realität, es ist als Wert-Initialisierung.Aber Wert-Initialisierung wird null-Initialisierung für alle Mitglieder eines Arrays von skalaren Typ).Wenn das, was Sie sind nach.

Wert ist zu beachten, dass es auch funktioniert, arbeiten für (arrays) - Klasse-Typen, ohne dass der Benutzer deklarierten Konstruktor, in dem Fall jedes Mitglied von Ihnen ist es Wert initialisiert:

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

Es ist nicht irgendeine Erweiterung oder so etwas.Es funktionierte, und verhielten sich in der gleichen Weise in C++98 zu.Nur war es dort genannten default-Initialisierung statt Wert-Initialisierung.Null-Initialisierung, jedoch ist in beiden Fällen für die skalaren oder arrays von skalaren oder POD-Typen.

Andere Tipps

Nein, aber es ist ziemlich einfach, eine neue Version zu erstellen, die wie calloc wirkt. Es kann in die gleiche Art und Weise durchgeführt werden, dass die nicht-throw-Version neu implementiert.

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

Jetzt können Sie die folgenden Aktionen neu zu bekommen mit zero'd Speichern

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

Darüber hinaus müssen Sie andere Dinge zu tun, wie neu definieren [], die recht geradlinig als gut.

Nein. Denken Sie auch gar nicht zu tun, so etwas wie:

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

Sie können Ihre VTABLE am Ende Wegwerfen (wenn Ihre Klasse hat).

würde ich empfehlen, Konstrukteure mit dem internen Speicher (Variablen) der Klasse zu löschen.

Nein. Es wird immer die zugewiesene Position (en), die im Fall von Primitiven tut nichts default-initialisiert werden. Sie werden es mit einem std :: uninitialized_fill_n Aufruf folgen oder ähnlich.

Sie können eine globale Überlastung der Betreiber new tun und haben es den rohen Speicher von calloc() greifen. Auf diese Weise der Speicher vor Konstrukteurs abgewischt wird laufen bekommen, so gibt es keine Probleme gibt.

Jede Klasse, die auf einer eigenen, neuen überschreibt nicht Ihre speziellen calloc()-basierte new bekommen, aber dann sollte die Klasse selbst richtig ohnehin initialisiert wird.

Vergessen Sie nicht, sowohl new und delete und die Array-Versionen ...

außer Kraft setzen

So etwas wie:

#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); 
}
Hinweis

, dass diese einfachen Versionen sind nicht ganz genau, was sie sein sollte - die new Betreiber sollten in einer Schleife laufen die new_handler Aufruf (wenn man installiert ist) und nur die bad_alloc Ausnahme werfen, wenn es keine new_handler ist. Oder so ähnlich, ich werde es so aussehen muß und später aktualisieren.

Oh, und Sie möchten vielleicht auch die no_throw Version als auch außer Kraft setzen.

ich verwende einen Makro:

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

, es zu benutzen:

Whatever* myWhatever = newclear(Whatever);

(diese verwendet „Platzierung neue“ wie einige andere Lösungen hier)

No.You auf Null manuell den Speicher aus. Denken Sie daran, new ist nicht nur über das Zuweisen von Speicher, sondern auch um über Konstruktoren initialisiert. Dies ist, wo calloc praktisch ist in C (was nicht initializer Funktionen hat). Sie sind frei, einen Wrapper über new zu schreiben oder sogar calloc verwenden, aber die meiste Zeit für nicht-POD-Objekte so viel macht keinen Sinn.

, wenn Sie darauf bestehen, nicht new verwenden, können Sie einfach verwenden Vektor. vector<char> buffer; buffer.resize(newsize); und der Inhalt wird auf Null gesetzt werden

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

Und Sie können die globalen neuen Betreiber überschreiben, wenn Sie möchten.

Sie können sagen:

vector <char> v( 100, 0 );

, die eine zusammenhängende Reihe von 100 Zeichen schafft neue Verwendung und initialisiert sie alle zu Null. Sie können dann auf das Array mit Vektor der Operator [], oder indem Sie:

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

Hinweis: Dies befreit Sie auch mit den zugewiesenen Speicher löschen rufen zu befreien.

Ja.

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

Für Arrays können Sie so etwas wie memset verwenden. Für Fenster verwenden Zeromemory oder SecureZeroMemory.

Edit:. Bitte beachten Sie @ litb die Post, er zeigt, wie Sie auf 0 für Arrays mit nicht direkter Initialisierung wie oben initialisieren

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top