2010-04-10 4 views
22

Ich weiß, dass Sie keine Initialisierungsliste für ein Array verwenden können. Ich habe jedoch von Möglichkeiten gehört, wie Sie ein Array von Zeigern auf NULL auf eine Art setzen können, die einer Initialisiererliste ähnlich ist.C++ Wie setzt man ein Array von Zeigern in einer Initialisiererliste auf null?

Ich bin mir nicht sicher, wie das gemacht wird. Ich habe gehört, dass ein Zeiger standardmäßig auf NULL gesetzt ist, obwohl ich nicht weiß, ob dies im C++ - Standard garantiert ist. Ich bin mir auch nicht sicher, ob die Initialisierung durch den neuen Betreiber im Vergleich zur normalen Zuweisung auch einen Unterschied machen kann.

Edit: Ich meine, dies in einer Header-Datei/Konstruktor Initialisierungsliste zu tun. Ich möchte es nicht in den Konstruktor einfügen, und ich möchte keinen Vector verwenden.

Antwort

27

Um ein Array von Zeigern auf NULL-Werte in Konstruktor Initialisiererliste zu setzen, können Sie die () initializer

struct S { 
    int *a[100]; 

    S() : a() { 
    // `a` contains null pointers 
    } 
}; 

Leider ist in der aktuellen Version der Sprache verwenden, die () initializer ist die einzige initializer, dass Sie kann mit einem Array-Element in der Konstruktorinitialisierungsliste verwendet werden. Aber anscheinend brauchen Sie das in Ihrem Fall.

Die () hat die gleiche Wirkung auf Arrays zugeordnet mit new[]

int **a = new int*[100](); 
// `a[i]` contain null pointers 

In anderen Kontexten können Sie die {} Aggregatinitialisierung verwenden, um den gleichen Effekt

int *a[100] = {}; 
// `a` contains null pointers 

Hinweis zu erreichen, dass es absolut keine Notwendigkeit, eine 0 oder eine NULL zwischen der {} drücken. Das leere Paar {} wird gut funktionieren.

+0

Ja! Das ist genau das, was ich wollte, danke :) – user233320

+5

+1 - Nur so nebenbei erfordert C, dass es mindestens einen Wert zwischen den Initialisierungsstreben gibt. C++ hat den leeren Klammerinitialisierer ('{}') hinzugefügt, weil es keinen Grund dafür gibt, dass der Standardwert eines Objekts "0" sein muss und der Code, der nach der Initialisierung eines Objekts fragt, keine Ahnung hat, was ein vernünftiger Standard sein könnte (besonders in Vorlagen). –

+1

Ich dachte 'int * a = new int [100]();' erzeugt einen Zeiger auf ein Array von ganzen Zahlen, die null initialisiert sind. 'A [i]' würde 0 enthalten und ein dereferenzierter Zeiger auf die (i + 1 sein) die ganze Zahl in diesem Array und nicht ein Nullzeiger. –

3

Normalerweise wird ein Array nicht standardmäßig initialisiert, aber wenn Sie ein oder mehrere Elemente explizit initialisieren, werden alle verbleibenden Elemente automatisch auf 0 initialisiert. Da 0 und NULL gleichwertig sind, können Sie daher ein Array von Zeigern auf NULL initialisieren dies wie:

float * foo[42] = { NULL }; // init array of pointers to NULL 
+1

Beachten Sie, dass "int foo1 [42] = {1};" nur in die erste zu 1 und die verbleibende zu 0, da C++ in der Regel Array-Elemente auf 0 setzt! In Ihrem Beispiel stellen Sie nur das erste Element auf 0 und das verbleibende auf 0. – amfcosta

+0

@amfcosta: Ich bin nicht sicher, warum Sie die Antwort für unklar halten oder warum sie eine Down-Vote verdient? Das OP fragte nach dem Initialisieren von Arrays von Zeigern auf "NULL". –

+0

Bitte sehen Sie meinen Kommentar. Das liegt daran, dass int foo1 [42] = {0}; ist irreführend. – amfcosta

0
void* p[10] = { 0 }; 
+0

Beachten Sie, dass dies das erste Element nur explizit auf 0 initialisiert, die verbleibenden werden standardmäßig von C++ auf Null initialisiert. Zum Beispiel "int foo1 [42] = {1};" nur in die erste zu 1 und die verbleibende zu 0, da C++ in der Regel Array-Elemente auf 0 setzt! – amfcosta

+0

Wichtiger ist, dass der Compiler die restlichen Einträge auf all-bits-zero initialisiert, was nicht garantiert ist, dass sie mit der Darstellung für einen Nullzeiger identisch sind. – kdopen

+0

@ kdopen Tatsächlich sind die _remaining_ Einträge OK; es gibt explizit '0', das könnte ein Problem sein - dh Sie erhalten 0-Initialisierung, wenn Sie _ nicht ausdrücklich 0 erwähnen.: S _ "Zero-Initialisierung wird [...] für Mitglieder von Wert-initialisierten Klassen-Typen durchgeführt, die keine Konstruktoren, einschließlich Wertinitialisierung von Elementen von Aggregaten, für die keine Initialisierer bereitgestellt werden. [...] Ein Null-initialisierter Zeiger ist der Nullzeigerwert seines Typs, selbst wenn der Wert des Nullzeigers nicht ganzzahlig Null ist. " _ http://en.cppreference.com/w/cpp/language/zero_initialization Seit C++ 11 verwenden Sie '{}'. –

2

ich bin nicht sicher, wie das gemacht wird. Ich habe gehört, dass ein Zeiger standardmäßig auf NULL gesetzt ist, obwohl ich nicht weiß, ob dies im C++ - Standard garantiert ist.
Es ist nicht durch den C++ - Standard garantiert. Eingebaute Typen (wie Zeiger) werden mit Müll gefüllt, sofern nicht anders festgelegt.

Ich bin auch nicht sicher, ob durch den neuen Betreiber Initialisierung im Vergleich zu normaler Zuordnung kann auch einen Unterschied machen.
Was meinen Sie mit "normale Zuweisung"? Wenn Sie über eine automatische Variable sprechen, dann können Sie dies tun:

MyType * pointers[2] = {}

und die Zeiger sollte auf NULL initialisiert werden.

+1

Zeiger werden nicht garantiert auf NULL initialisiert, genauso wie Ints nicht in vielen Kontexten auf 0 initialisiert werden. Beachten Sie, dass Ihr Beispiel äquivalent zu '{NULL, 0}' und '{}' ist (wobei letzteres bevorzugt wird), anstatt einen Wert für alle Elemente im Array anzugeben. –

+0

@RogerPate Ich weiß, diese Antwort ist Jahre zu spät, aber jetzt behoben. :) –

7

Sie können von Array zu std::vector wechseln und

std::vector<T*> v(SIZE); 

Die Werte verwenden werden automatisch durch NULL s initialisiert werden. Dies ist der bevorzugte C++ Weg.


Update: Da C++ 11 gibt eine weitere Möglichkeit ist: Verwendung

std::array<T*, SIZE> array = {}; 

Dieses eher wie eine korrigierte Version des C-style-Array verhält (insbesondere dynamische Zuteilungen vermeidet), trägt seine Größe herum und zerfällt nicht zu einem Zeiger. Die Größe muss jedoch zum Zeitpunkt der Kompilierung bekannt sein.

+1

Es sei denn, das OP möchte kein dynamisch sortiertes Array. –

+0

@ Billy: Nun, das OP könnte einfach die Möglichkeit zur dynamischen Sizing ignorieren. C++ - Style-Arrays sind im Allgemeinen eine gute Sache. – Vlad

+3

Wenn die Größe zur Kompilierungszeit bekannt ist, sind die eingebauten Arrays jedoch besser. Es ist besser, wenn möglich eine dynamische Zuweisung zu vermeiden. 'Vektoren' sollten verwendet werden, wenn die Größenkonstante zur Kompilierungszeit nicht bekannt ist. –

-1

Wenn Sie ein Element-Array haben, gibt es keine Möglichkeit zur Initialisierung, es sei denn, es handelt sich um ein statisches Element. Wenn das Array kein statisches Element ist, müssen Sie es im Körper des Konstruktors ausfüllen.

Das heißt, die Chancen sind Sie wirklich besser dran mit einem std::vector verwenden. Abgesehen von technischen Gründen wie der Nichtverfügbarkeit einer Standard-STL für Ihre Plattform oder der etwas geringeren Leistung ist ein std::vector besser als ein Array nach allen Kriterien. Wenn die Leistung das Problem ist, stellen Sie sicher, dass Sie ein Profil erstellt haben und wissen Sie, dass es ein Problem ist.

Verwandte Themen