Zum Inhalt springen

Array mit int als größe deklarieren


Net-srac

Empfohlene Beiträge

Tachchen,

ich hab 1 Methode, die als parameter einen integer übergeben bekommt. Nun hatte ich vor einen array zu erzeugen, der der größe dieses integer entspricht. Ich bekomm nur immer einen Kompilerfehler, das ein konstanter Wert erwartet wird?!

Was mach ich falsch? Oder geht das in C++ nicht?

 

bool dynIP::connect(int count_ip)
{
....
int lSocket[count_ip];

....

[/PHP]

Link zu diesem Kommentar
Auf anderen Seiten teilen

Es ist kein Standard, wenn man die Größe eines Arrays nicht mit einem konstantem Ausdruck angibt. Der gcc erlaubt dies, aber wie gesagt es ist kein Standard und Dein Compiler erlaubt es, wie Du gemerkt hast auch nicht. Dies tut er zurecht.

Trotzdem gibt es eine Lösung für Dich. In C++ gibt es das Schlüsselwort new. Mit diesem kannst Du dynamisch Arrays anlegen.

int *array = new int[deineGewuenschteGroesse]

Was ich fast vergessen hätte: Natürlich muß der Speicher auch wieder freigegeben werden. dies tut man am besten mit delete[] array.

HTH

Jan

Link zu diesem Kommentar
Auf anderen Seiten teilen

Originally posted by nic_power

Das geht nicht. Da die Groesse des Arrays zur Compilezeit nicht bekannst ist, musst Du es in diesem Fall dynamisch erzeugen (new, malloc).

Ich habe gerade nochmal nachgesehen, es geht doch ;). Nach ISO C99 ist dies erlaubt und wird auch vom gcc unterstuetzt. Es gibt allerdings ein paar Unterschiede zu "normalen" Arrays. Der Speicherplatz wird an der Stelle der Deklaration allokiert. Der Speicher wird freigegeben, sowie man den Scope verlaesst. Naeheres im gcc Manual: http://gcc.gnu.org/onlinedocs/gcc-3.2/gcc/Variable-Length.html#Variable%20Length

Nic

Link zu diesem Kommentar
Auf anderen Seiten teilen

Originally posted by nic_power

Ich habe gerade nochmal nachgesehen, nach ISO C99 ist dies erlaubt und wird auch vom gcc unterstuetzt. Es gibt allerdings ein paar Unterschiede zu "normalen" Arrays. Der Speicherplatz wird an der Stelle der Deklaration allokiert. Der Speicher wird freigegeben, sowie man den Scope verlaesst.

Nic

Wenn aber die Größe des Arrays zur Compilezeit nicht bekannt ist ( die Größe ist ja in diesem Fall ein formaler Funktionsparameter) wie groß ist dann das Array das vom Compiler angelegt wird ?

Oder wird das dann intern mittels eines malloc oder new gelöst ?

Frank

Link zu diesem Kommentar
Auf anderen Seiten teilen

Originally posted by fmarx2000

Wenn aber die Größe des Arrays zur Compilezeit nicht bekannt ist ( die Größe ist ja in diesem Fall ein formaler Funktionsparameter) wie groß ist dann das Array das vom Compiler angelegt wird ?

Oder wird das dann intern mittels eines malloc oder new gelöst ?

Frank

Koennte man vermuten, ist aber nicht der Fall. Der notwendige Speicherplatz wird zur Laufzeit auf dem Stack beschafft (wie auch der Speicherplatz fuer jede andere Variable die innerhalb einer Funktion oder eines Funktionsblockes deklariert wird). Falls Interesse besteht, wuerde ich mal ein passendes Beispiel raussuchen.

Nic

Link zu diesem Kommentar
Auf anderen Seiten teilen

Originally posted by nic_power

Koennte man vermuten, ist aber nicht der Fall. Der notwendige Speicherplatz wird zur Laufzeit auf dem Stack beschafft (wie auch der Speicherplatz fuer jede andere Variable die innerhalb einer Funktion oder eines Funktionsblockes deklariert wird). Falls Interesse besteht, wuerde ich mal ein passendes Beispiel raussuchen.

Nic

Ahh so, d.h. es verält sich wie eine automatische Variable nur wird das ganze eben dann mit variabler Größe auf dem Stack abgelegt.

Ich finde das Feature nicht so toll, Stacks sind ja in der Regel nicht so gross und um sich etwas kompfort zu erkaufen kann man sich schnell ins Knie schiessen.

Eine saubere Lösung mit new und delete [] fände ich da besser.

Frank

Link zu diesem Kommentar
Auf anderen Seiten teilen

Originally posted by fmarx2000

Ahh so, d.h. es verält sich wie eine automatische Variable nur wird das ganze eben dann mit variabler Größe auf dem Stack abgelegt.

Ich finde das Feature nicht so toll, Stacks sind ja in der Regel nicht so gross und um sich etwas kompfort zu erkaufen kann man sich schnell ins Knie schiessen.

Stacks werde im Allgemeinen nur durch die Groesse des Verfuegbaren Speichers bzw. irgendwelche Kernelvariablen beschraenkt ("maxssize" bei HPUX beispielsweise).

Nic

Link zu diesem Kommentar
Auf anderen Seiten teilen

Originally posted by nic_power

Stacks werde im Allgemeinen nur durch die Groesse des Verfuegbaren Speichers bzw. irgendwelche Kernelvariablen beschraenkt ("maxssize" bei HPUX beispielsweise).

Nic

Komisch ich dachte Heaps sind das, die werden doch durch die Größe des Hauptspeichers beschränkt.

Ich habe das noch so in Erinnerung das uns unser Prof. immer vor zu tiefen Rekursionen gewarnt hat weil dann der Stack in den Heap wachsen kann.

Ist auch egal, ich finde des trotzdem nicht gut.

Frank

Link zu diesem Kommentar
Auf anderen Seiten teilen

Originally posted by nic_power

Stacks werde im Allgemeinen nur durch die Groesse des Verfuegbaren Speichers bzw. irgendwelche Kernelvariablen beschraenkt ("maxssize" bei HPUX beispielsweise).

Unter Windows wird die Stackgröße ins Binary hineinkompiliert und ist damit durchaus beschränkt. Gibt es wirklich Systeme, bei denen eine simple rekursive Endlosschleife den kompletten Speicher frisst?
Link zu diesem Kommentar
Auf anderen Seiten teilen

Als ich erwähnte, daß der gcc die Größenangabe als Variable erlaubt, wollte ich damit nicht sagen, daß ich es gut finde. Ich persönlich mag es auch nicht und würde es auch nie benutzen. Auch nicht, wenn ich speziell für gcc entwickeln würde. Auch finde ich es nicht gut, daß dieses Verhalten Einzug in den C99 Standard gehalten hat. Es ist aber definitiv kein Standard von C++.

Wie schon weiter oben erwähnt wurde ist die schönste und sauberste Methode, wenn man mit new und delete arbeitet.

Jan

Link zu diesem Kommentar
Auf anderen Seiten teilen

Originally posted by Klotzkopp

Unter Windows wird die Stackgröße ins Binary hineinkompiliert und ist damit durchaus beschränkt. Gibt es wirklich Systeme, bei

denen eine simple rekursive Endlosschleife den kompletten Speicher frisst?

Theoretisch ja, praktisch nein. Unixoide Systeme kontrollieren die maximale Groesse des

Stacksegments ueber eine Variable, die vom Nutzer gesetzt werden kann. Erreicht die Groesse des Stacks den Wert der Variablen generiert der Kernel für den betroffenen Prozess einen Core-Dump mit einer entsprechenden Fehlermeldung.

Nic

Link zu diesem Kommentar
Auf anderen Seiten teilen

Originally posted by Orffi

Als ich erwähnte, daß der gcc die Größenangabe als Variable erlaubt, wollte ich damit nicht sagen, daß ich es gut finde. Ich persönlich mag es auch nicht und würde es auch nie benutzen. Auch nicht, wenn ich speziell für gcc entwickeln würde. Auch finde ich es nicht gut, daß dieses Verhalten Einzug in den C99 Standard gehalten hat. Es ist aber definitiv kein Standard von C++.

Wie schon weiter oben erwähnt wurde ist die schönste und sauberste Methode, wenn man mit new und delete arbeitet.

Jan

Du solltest aber nicht ausser acht lassen, das new und delete deutlich mehr Zeit kosten, da es sich hier um eine komplette Speicherverwaltung handelt. Speicher auf dem Stack kostet "zeitmaessig" fast nichts, da man nur den Stackpointer entsprechend anpassen muss. D.h. bei Funktionen mit kleinen Arrays, die sehr haeufig aufgerufen werden, kann diese Methode unter Umstaenden deutlich schneller sein (und ist obendrein noch mit Null Aufwand zu implementieren). Ich persoenlich wuerde aber auch eher dazu tendieren, mit den Speicher auf "klassische" Weise zu besorgen.

Nic

Link zu diesem Kommentar
Auf anderen Seiten teilen

So, und hier noch ein Beispiel mit Kommentaren, wie der gcc das folgende Programm umsetzt. Uebrigens auch ein sehr schoenes Beispiel fuer die Komplexitaet moderner CPUs (siehe auch Diskussion um das "Fachinformatiker-OS".


int main(int argc, char **argv)

{

  func(atoi(argv[1]));

}


int func(int size)

{

  int array[size];


  printf("Array Size = %d Bytes\n", size);

}


main:   # int main(int argc, char **argv)

        # {

        #   /* Defaultstack Anlegen */

        save    %sp, -112, %sp   


        #   /* %i0   enthaelt pointer auf argv */

        #   /* %i0+4 zeigt demnach auf den ersten Übergabearameter */

        # int tmp=atoi(argv[1]);

        call    atoi, 0

        #   /* %o0 ist Übergabeparameter an die Funktion "atoi()" */

        #   /* das Laden des Parameter (argv[1]) erfolgt im Delayslot */

        ld      [%i1+4], %o0

        #   /* das Ergebnis (tmp) wird ins register %o0 geschrieben */

        #   /* Aufruf unserer Funktion */

        # func(tmp); /*  entspricht func(atoi(argv[1])) */

        call    func, 0

        #   /* aufraeumen und Programmende */

        # }

         restore %g0, %o0, %o0

        nop

_string:

        .asciz  "Array Size = %d Bytes\n"


func:   # int func(int size) 

        # {

        #   /* size wird in register %i0 übergeben (%o0 beim Aufrufer) */

        #   /* Defaultstack Anlegen */

        save    %sp, -112, %sp


        #   int array[size];

        #   /* da ein "int" 4 byte gross ist, muss fuer  */

        #   /* 4*size Bytes Platz auf dem Stack geschaffen werden */

        #   int tmp=4*size; /* entspricht %o4=4*%i0 */

        sll     %i0, 2, %o4


        #   int arg01=size;

        #   /* %o1=%i0, %o1 enthaelt jetzt die Groesse des Arrays also size */

        mov     %i0, %o1


        #   /* SPARC-V9 Architekturen arbeiten mit Stacks auf 8 Byte */

        #   /* boundaries, die folgenden Anweisungen erledigen das */

        #   /* entsprechende Alignment, als Ergebnis steht in reg %o2 */

        #   /* Die Anzahl der auf dem Stack benötigten Bytes */

        add     %o4, 7, %o3

        mov     %sp, %i0

        and     %o3, -8, %o2


        #   /* erste Haelfte der Adresse von String nach %g1 laden */

        sethi   %hi(_string), %g1


        #   /* Stackpointer anpassen, damit ist für "size" Bytes Platz auf */

        #   /* dem Stack */

        sub     %sp, %o2, %sp


        # printf(string, size); /* printf("Array Size = %d Bytes\n", size); */

        #   /* erste parameter an printf in %o0, zweiter parameter in %o1 */

        call    printf, 0


        #   /* zweite Haelfte der Adresse des Strings mit %g1 verknuepfen */

        #   /* und das Ergebnis nach %o0 schreiben, wird vor dem Call printf */

        #   /* ausgefuehrt */

        or      %g1, %lo(_string), %o0


        mov     %i0, %sp

        nop

        #   /* zurueck zum aufrufer */

        ret


        #   /* und vorher den Stack wiederherstellen */

        restore


Link zu diesem Kommentar
Auf anderen Seiten teilen

Originally posted by nic_power

Theoretisch ja, praktisch nein. Unixoide Systeme kontrollieren die maximale Groesse des

Stacksegments ueber eine Variable, die vom Nutzer gesetzt werden kann. Erreicht die Groesse des Stacks den Wert der Variablen generiert der Kernel für den betroffenen Prozess einen Core-Dump mit einer entsprechenden Fehlermeldung.

Nic

Ich denke auch mal das es unter NT auch wie unter UNIX ist dass jeder Prozess einen bestimmten Speicher als Stack bekommt und nicht den gesamten Systemspeicher, was dann doch schon eine Einschränkung ist.

Wenn ich eine Rekursion nur lange genug ausführe kommt es zum überlauf da ja ständig Zeug auf den Stack gelegt wird aber es nicht mehr runtergeholt wird.

Frank

Link zu diesem Kommentar
Auf anderen Seiten teilen

Dein Kommentar

Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...