Was ist der sichere Weg, um mehrdimensionale Arrays mit std :: fill zu füllen?

8

Hier ist, was ich benutze:

%Vor%

(Update: Ich hätte früher klarstellen sollen, dass ich das in einer Klasse verwende.)

    
Truncheon 16.10.2010, 09:14
quelle

3 Antworten

13

Die einfache Methode zur Initialisierung auf 0 das Array ist in der Definition:

%Vor%

Wenn Sie std::fill verwenden möchten oder das Array zurücksetzen möchten, finde ich das etwas besser:

%Vor%

Die fill ausgedrückt in der Array-Größe ermöglicht es Ihnen, die Dimensionen zu ändern und die fill unberührt zu lassen. Die sizeof(flags[0][0]) ist in Ihrem Fall 1 ( sizeof(char)==1 ), aber Sie können sie dort belassen, falls Sie den Typ an irgendeinem Punkt ändern möchten.

In diesem speziellen Fall (Array von Flags --integral type) könnte ich sogar memset verwenden, auch wenn es die sichere Alternative ist (das wird brechen) Wenn der Array-Typ in einen Nicht-Pod-Typ geändert wird:

%Vor%

Beachten Sie, dass in allen drei Fällen die Array-Größen nur einmal eingegeben werden und der Compiler den Rest ableitet. Das ist ein wenig sicherer , da es weniger Platz für Programmiererfehler lässt (die Größe an einer Stelle ändern, in den anderen vergessen).

BEARBEITEN: Sie haben den Code aktualisiert, und er wird nicht kompiliert, da das Array privat ist und Sie versuchen, es extern zu initialisieren. Abhängig davon, ob Ihre Klasse tatsächlich ein Aggregat ist (und es als solches beibehalten möchte) oder ob Sie der Klasse einen Konstruktor hinzufügen möchten, können Sie verschiedene Ansätze verwenden.

%Vor%

Auch wenn array öffentlich sein soll, ist die Verwendung eines Konstruktors möglicherweise ein besserer Ansatz, da es garantiert, dass array ordnungsgemäß in allen Instanzen der Klasse initialisiert wird, während die externe Initialisierung vom Benutzercode abhängt nicht zu vergessen, die Anfangswerte zu setzen.

[1] Wie @Oli Charlesworth in einem Kommentar erwähnt hat, ist die Verwendung von Konstanten eine andere Lösung für das Problem, Größen an mehr als einer Stelle angeben zu müssen (und synchron zu halten). Ich habe diesen Ansatz hier mit einer noch anderen Kombination verwendet: Ein Zeiger auf das erste Byte außerhalb des zweidimensionalen Arrays kann erhalten werden, indem die Adresse der ersten Spalte eine Zeile hinter dem zweidimensionalen Array angefordert wird. Ich habe diesen Ansatz nur verwendet, um zu zeigen, dass es möglich ist, aber es ist nicht besser als andere wie &array[0][0]+(rows*cols)

    
David Rodríguez - dribeas 16.10.2010, 09:21
quelle
2

es ist sicher, ein zweidimensionales Array ist ein Array von Arrays. Da ein Array einen zusammenhängenden Speicher belegt, wird es auch das ganze multidimensionale Ding sein. Also ja, es ist OK, sicher und tragbar. Angenommen, Sie fragen sich NICHT nach dem Stil, der von anderen Antworten abgedeckt wird (da Sie Flags verwenden, empfehle ich Ihnen std::vector<std::bitset<80> > myFlags(26) )

    
Armen Tsirunyan 16.10.2010 09:17
quelle
0

Soll char[80] ein Ersatz für einen echten String-Typ sein? In diesem Fall empfehle ich Folgendes:

%Vor%

Oder wenn Sie einen C ++ - Compiler haben, der Initialisierungslisten unterstützt, zum Beispiel einen neueren g ++ - Compiler:

%Vor%     
fredoverflow 16.10.2010 10:25
quelle