Initialisieren eines C-Struct-Arrays mit einer Größe, die bei der Kompilierung nicht bekannt ist

7

Ich habe keine genaue Antwort auf diese Frage gefunden, also ist es entweder eine dumme Frage oder einfach nur offensichtlich. Ich würde gerne wissen, ob es zu undefiniertem Verhalten führen würde.

Ich habe einen bestimmten Strukturtyp definiert:

%Vor%

Ich brauche mehrere Instanzen dieser Struktur (wie im struct-Array), aber die Anzahl der Objekte ist zur Kompilierzeit unbekannt.

Ist es richtig, es so zu initialisieren?

%Vor%

Ist das sicher? Der memset() -Teil ist, worüber ich mir Sorgen mache.

    
Tomislav 31.12.2012, 12:36
quelle

4 Antworten

9
  

Ist das sicher? Der memset () Teil ist, worüber ich mir Sorgen mache.

Ja, es ist sicher, in dem Sinne, dass dies kein undefiniertes Verhalten verursacht (Pufferüberläufe, nicht initialisierte Werte, etc.).

Allerdings werden Ihre Werte nicht unbedingt auf Null gesetzt. memset setzt die Bits auf 0, aber dies ist nicht notwendigerweise dasselbe wie z. a float auf einen Wert von 0 (obwohl es in der Praxis auf den meisten normalen Plattformen in Ordnung ist).

    
Oliver Charlesworth 31.12.2012, 12:38
quelle
10

Die Verwendung von malloc gefolgt von memset ist soweit OK, aber Sie sollten stattdessen den (nicht verwendeten) calloc berücksichtigen. Zum Beispiel:

%Vor%

Dies wird Speicher für die erforderliche Anzahl von Elementen zuweisen, und initialisieren sie auf binäre Null.

    
cdarke 31.12.2012 12:43
quelle
4
  

Ist das sicher? Der memset () Teil ist, worüber ich mir Sorgen mache.

Sie haben recht, wenn Sie sich Sorgen machen - Ihr memset setzt einfach alle Bits auf Null, was die Mitglieder nicht unbedingt auf 0 setzt.

Zum Beispiel garantiert nichts, dass alle Bits 0 für einen Float tatsächlich 0 bedeuten. Das Gleiche gilt für einen Zeiger: wenn man all-bits-0 macht, heißt das nicht unbedingt, dass es NULL ist.

BEARBEITEN

NULL kann oder kann nicht als all-bits-0 dargestellt werden. Zitieren der C FAQ:

  

Die interne (oder Laufzeit-) Darstellung eines Null-Zeigers, der   oder möglicherweise nicht alle-Bits-0 und die für verschiedene unterschiedlich sein können   Zeigertypen.

    
cnicutar 31.12.2012 12:38
quelle
1

Die memset in Ihrem Code wird alle Bits auf 0 setzen, was vielleicht nicht das ist, was Sie tun wollen. Insbesondere ist nicht garantiert, dass ein Zeiger mit allen Null-Bits der Nullzeiger ist. Auch kein schwebender Wert mit allen Null-Bits ist Null.

Wenn Sie möchten, dass Ihr Code vollständig portierbar ist, sollten Sie jedes Element initialisieren.

%Vor%

Oder Sie könnten die Initialisierung mit einem C99-Verbindungsliteral durchführen:

%Vor%

In der Praxis müssen Sie hart arbeiten, um eine C-Implementierung zu finden, bei der der obige Code ein anderes Ergebnis hat als Ihre Variante, die memset verwendet.

    
David Heffernan 31.12.2012 12:53
quelle