Externe Deletion für ein Array?

Lesezeit: 4 Minuten

Benutzer-Avatar
Ravi Gupta

Ich habe ein Array in einer Datei definiert und in einer anderen muss ich es verwenden, z.

/* a.c - defines an array */

int a[] = {1,2,3,4,5,6,7,8,9}; 


/* b.c - declare and use it. */

#define COUNT ((sizeof a)/(sizeof int))
extern int a[];  //size of array

.
.
.

int i;
for(i=0; i<COUNT; i++)
  printf("%d", a[i]);
.
.
.

Wenn ich jetzt versuche, es zu kompilieren, wurde mir der Fehler angezeigt, dass sizeof nicht für unvollständige Typen verwendet werden kann.

Kann mir jemand sagen, wie man mit einem solchen Fall in C/C++ umgeht? Ich möchte nicht in ac tiefgestellt werden

Danke im Voraus

  • Ich bin heute auf dieses Problem gestoßen. Ich dachte, wenn der Linker die Referenzen externer Objekte auflösen kann, dann kann er auch ihre Größen auflösen … Aber es scheint, dass die Linker noch nicht so schlau sind …

    – Kalmarius

    18. Dezember 2013 um 19:40 Uhr

  • Beim Kompilieren von bc kennt der Compiler die Größe von nicht a – Sie haben es nicht gesagt. Alles, was es weiß, dass ein int-Array aufgerufen wird a existiert in einem anderen Modul. Der Verknüpfungsprozess löst Objektadressen, aber keine Größen auf.

    – Seva Alexejew

    15. Dezember 2018 um 15:02 Uhr

Benutzer-Avatar
Markus Wilkins

Sie könnten so etwas wie das Folgende einfügen a.c und extern dann aus b.c.

Im Wechselstrom:

int a[] = {1, 2, 3};
const int lengthofa = sizeof( a ) / sizeof( a[0] );

Und dann in bc:

extern int a[];
// the extern (thanks Tim Post) declaration means the actual storage is in another 
// module and fixed up at link time.  The const (thanks Jens Gustedt) prevents it
// from being modified at runtime (and thus rendering it incorrect).
extern const int lengthofa;

void somefunc() {
  int i;
  for ( i = 0; i < lengthofa; i++ )
    printf( "%d\n", a[i] );
}

  • Es ist eigentlich falsch, dass die const würde Laufzeitänderungen verhindern. Abgesehen von der beabsichtigten Modifikation durch Umformungen ((int)lengthofa = <something>), haben auch Pufferüberläufe eine gute Chance, den Wert zu verändern. Ich sehe keinen Grund, die Array-Größe in diesem Fall nicht explizit anzugeben (vorzugsweise durch Verwendung eines ‘#define MAGICNUM ‘. Oder so etwas wie #define LENGTHOFA(a) sizeof (a) / sizeof ((a)[0]) stattdessen.

    – polynomial_donut

    16. Oktober 2018 um 17:44 Uhr


  • WENN Sie MISRA – C einhalten müssen, tun Sie dies nicht extern int a[]MISRA – C:2004, 8.12 “Wenn ein Array mit externer Verknüpfung deklariert wird, wird seine Größe muss explizit angegeben oder implizit durch Initialisierung definiert werden.”

    – Undefiniertes Verhalten

    14. Januar 2019 um 13:28 Uhr


Wenn Sie möchten, dass Ihre Arraygröße als Konstante zur Kompilierzeit zugänglich ist, haben Sie keine andere Wahl, als die Arraygröße explizit in der anzugeben extern Deklaration des Arrays

extern int a[9];

In diesem Fall liegt es in Ihrer Verantwortung, sicherzustellen, dass die Array-Größe zwischen den konsistent ist extern Deklaration und Definition. Sie können dafür eine Manifest-Konstante verwenden, aber es liegt dennoch in Ihrer Verantwortung, sicherzustellen, dass die Anzahl der Initialisierer zwischen den {} und die angegebene Größe sind gleich.

Wenn Sie die Arraygröße nicht als Konstante zur Kompilierzeit haben möchten, können Sie tun, was Mark Wilkins in seiner Antwort vorschlägt.

  • Wenn Sie diesen Pfad verwenden und Visual Studio verwenden, wird die Anzahl der Elemente in einer QuickInfo angezeigt, wenn Sie den Mauszeiger über die Deklaration bewegen.

    – Tschumann

    23. Dezember 2018 um 5:38 Uhr

Der Compiler verfügt beim Kompilieren von bc nicht über genügend Informationen, um die Größe des Arrays zu bestimmen. Diese Informationen befinden sich nur in ac, wo sich Ihre Initialisiererliste im Geltungsbereich befindet.

Sie müssen die Größe irgendwie mitteilen. Eine Methode besteht darin, eine int-Konstante mit der Größe zu definieren und diese ebenfalls extern. Eine andere Möglichkeit wäre die Verwendung eines Sentinels (ein Wert außerhalb Ihres gültigen Datenbereichs), um das Ende des Arrays anzuzeigen.

Ich würde #define ARRAY_MAX (or whatever) in einem externen Header, der im Allgemeinen zum Definieren solcher Dinge verwendet wird, dann fügen Sie diesen Header in beide Dateien ein, die ihn benötigen. Dies funktioniert gut, wenn Sie dazu neigen, die meisten, wenn nicht alle von Ihnen zu behalten defines in einem oder zwei zentralen Headern.

Meiner Meinung nach wird es nicht kompiliert, wenn Sie keine Definition haben und mit sizeof a in einer Datei definieren.

Dateien werden als *.obj / *.a Dateien kompiliert und gespeichert. Sie können Arrays aus anderen Dateien dank der Extern-Deklaration verwenden, die nach dem Kompilieren beim Linken überprüft wird.

Sie wollen define deklarieren (hier muss der Präprozessor helfen. Er wird vor dem Compilator ausgeführt).

Vor der Kompilierung erhalten Sie also kein Array aus einer anderen Datei …

Benutzer-Avatar
Haari

Fügen Sie die Variable nur so in die Header-Datei ein:

#ifndef A_DEF
#define A_DEF
int a[] = {1,2,3,4,5,6,7,8,9}; 
#endif

Die bedingte Kompilierung erlaubt keine Neudefinition von Variablen. Somit haben Sie von überall Zugriff darauf.

1364320cookie-checkExterne Deletion für ein Array?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy