1. Weiterleitung zu NetzLiving.de
  2. Forum
    1. Unerledigte Themen
  3. zum neuen Forum
  • Anmelden
  • Suche
Dieses Thema
  • Alles
  • Dieses Thema
  • Dieses Forum
  • Seiten
  • Forum
  • Erweiterte Suche
  1. Informatik Forum
  2. Webmaster & Internet
  3. Entwicklung

C: Segmentation Fault bei großem Array

  • Gianna
  • 5. Juni 2004 um 21:19
  • Unerledigt
Hallo zusammen,

das Informatik-Forum geht in den Archivmodus, genaue Informationen kann man der entsprechenden Ankündigung entnehmen. Als Dankeschön für die Treue bekommt man von uns einen Gutscheincode (informatikforum30) womit man bei netzliving.de 30% auf das erste Jahr sparen kann. (Genaue Infos sind ebenfalls in der Ankündigung)

Vielen Dank für die Treue und das Verständnis!
  • Gianna
    Punkte
    952
    Beiträge
    162
    • 5. Juni 2004 um 21:19
    • #1

    [font=Verdana, Arial, Helvetica, sans-serif]Ich steh mit meinen C-Kenntnissen hier an, vielleicht kann mir wer von euch helfen:

    Ich hab ein Programm, in dem ein 2d-Array mit Float-Werten ininitialisiert wird, wobei die Größe durch zwei Variablen angegeben wird und damit von der Eingabe abhängt. Ausgeführt wird das Programm unter Linux. Und das Problem ist, ab einer gewissen Arraygröße bricht das Programm mit einem "Segmentation Fault" ab.

    Diese Werte sind etwa [16000][180].

    Dabei tritt der Fehler direkt bei der Initialisierung des Arrays auf, egal ob mit "float positions[][]" oder mit calloc.

    Hat wer eine Idee wie ich das wegkrieg?[/font]

  • Plantschkuh!
    Punkte
    6.173
    Beiträge
    1.181
    • 5. Juni 2004 um 22:50
    • #2

    Die Frage ist sehr schwer zu beantworten, ohne deinen Code zu kennen. Poste am besten eine kleine, abgespeckte Version des Programms.

  • Gianna
    Punkte
    952
    Beiträge
    162
    • 6. Juni 2004 um 13:25
    • #3

    ich glaub nicht, dass es sinn macht, den code zu posten, da er alleine eh nicht rennt weil das ganze in ein größeres projekt eingebettet ist. eine abgespeckte version wäre etwa sowas

    int x = 16000;
    int y = 180;
    float positions[x][y];

    was nicht viel aussagt...

    x und y werden in meinem programm nicht so initialisiert sondern berechnet, aber dort steckt auch nicht das problem, da die großen zahlen die dort rauskommen auf alle fälle stimmen.

    ich bin mir 100%ig sicher, dass das problem bei der initialisierung auftritt und mit dem rest nichts zum tun hat. erstens hab ich das ganze mit printfs umrahmt,

    printf(" A ");
    float positions[][]; bzw. calloc
    printf(" B ");

    zweitens hab ich die zeile an unterschiedlichen stellen im programm ausprobiert (was nichts ändert) und drittens rennt das programm mit kleineren arrays fehlerlos.

    hat sonst keiner eine idee?

  • Lord Binary
    Punkte
    3.301
    Beiträge
    647
    • 6. Juni 2004 um 13:38
    • #4

    Naja, Dir ist schon bewußt, daß das grob überschlagen ca 10MB Speicher braucht ?

    Wenn das Array jetzt z.B am Stack gespeichert wird -> i.A ein bissi zu viel.

    int x = 16000;
    int y = 180;
    float positions[x][y];

    funktioniert/compiliert so überigens sicher mit keinem C/C++ Compiler.

    Entweder dynamsich anlegen, dann ist es sowieso nicht mehr am Stack gespeichert. Und der Code zum Speicherreservieren für das Array mit malloc bzw new ist entscheidend.
    Oder const int x= ...
    Oder ist positions gar eine Klasse mit überladenem [] Operator ?
    Glaub ich nicht, denn [][] ist recht tricky mit Operator overloading hinzubekommen.

    Kurzum: Da ist IMHO immer noch zu wenig Code um irgendwas Sinnvolles sagen zu können.

    Mfg, LB

  • Gianna
    Punkte
    952
    Beiträge
    162
    • 6. Juni 2004 um 14:11
    • #5

    ich habs mittlerweile hinbekommen. genau das war das problem, ich hab zuviel speicher in einem block angefordert.

    die lösung (falls wen interessiert):

    zuerst ** positions = (float **) malloc(1600 * sizeof(float))

    und dann für alle elemente aus positions
    positions[] = (float *) malloc(180 * sizeof(float))

  • Plantschkuh!
    Punkte
    6.173
    Beiträge
    1.181
    • 6. Juni 2004 um 14:16
    • #6
    Zitat von Kuschelmaus

    ich glaub nicht, dass es sinn macht, den code zu posten, da er alleine eh nicht rennt weil das ganze in ein größeres projekt eingebettet ist.


    Deswegen hab ich ja gemeint, du sollst ihn abspecken, aber eben so weit, daß du noch ein kleines, lauffähiges Programm hast, das deinen Fehler demonstriert. Also sowas:

    C
    #include <stdio.h>
    #include <stdlib.h>
    
    
    int main(void)
    {
        unsigned int m, n;
        float **array;
        float *data;
        unsigned int i, j;
    
    
        if (scanf("%u %u", &m, &n) == 2)
        {
            printf("m = %u, n = %u\n", m, n);
            /* lege großen Speicherblock an */
            data = malloc(m * n * sizeof *data);
            /* lege Array von Pointern an */
            array = malloc(m * sizeof *array);
            if (data == NULL || array == NULL)
            {
                puts("data oder array konnte nicht angelegt werden");
                exit(EXIT_FAILURE);
            }
            /* setze Pointer an den Anfang jeder "Spalte" */
            for (i = 0; i < m; i++)
                array[i] = data + i * n;
            /* teste den Speicher */
            for (i = 0; i < m; i++)
                for (j = 0; j < n; j++)
                    array[i][j] = i * n + j;
            puts("alles ok");
            /* gebe Pointer und Gesamtspeicherblock frei */
            free(array);
            free(data);
        }
    
        return 0;
    }
    Alles anzeigen


    oder auch:

    C
    #include <stdio.h>
    #include <stdlib.h>
    
    
    int main(void)
    {
        unsigned int m, n;
        float **array;
        unsigned int i, j;
    
    
        if (scanf("%u %u", &m, &n) == 2)
        {
            printf("m = %u, n = %u\n", m, n);
            /* erste Dimension anlegen: ein Array von Pointern, für die
             * dann jeweils eine Spalte der Matrix angelegt wird */
            array = malloc(m * sizeof *array);
            if (array == NULL)
            {
                puts("array konnte nicht angelegt werden");
                exit(EXIT_FAILURE);
            }
            for (i = 0; i < m; i++)
            {
                /* erzeuge i-te Spalte */
                array[i] = malloc(n * sizeof *array[i]);
                if (array[i] == NULL)
                {
                    printf("array[%u] konnte nicht angelegt werden", i);
                    exit(EXIT_FAILURE);
                }
                /* weise jedem Element des Arrays einen Wert zu.
                 * Eventuelle Probleme sollten spätestens hier
                 * auftauchen. */
                for (j = 0; j < n; j++)
                    array[i][j] = n * i + j;
            }
            puts("alles ok soweit");
            /* gebe einzelne Spalten frei */
            for (i = 0; i < m; i++)
                free(array[i]);
            /* gebe Spaltenarray frei */
            free(array);
        }
    
        return 0;
    }
    Alles anzeigen


    Die erste Variante legt dabei einen großen Speicherblock für die gesamte Matrix an und erzeugt dynamisch Pointer, die jeweils an den Anfang einer Spalte zeigen. Die zweite Version legt für jede Spalte ein eigenes dynamisches Array an, hier ist der Speicherblock für die gesamte Datenstruktur nicht zusammenhängend.
    Beide funktionieren bei mir tadellos, z.B. mit dem Input "16000 1800". Ob sie wirklich korrekt sind, ist eine andere Sache ;)

  • jeuneS2
    Punkte
    1.227
    Beiträge
    238
    • 6. Juni 2004 um 17:50
    • #7
    Zitat von Lord Binary


    int x = 16000;
    int y = 180;
    float positions[x][y];

    funktioniert/compiliert so überigens sicher mit keinem C/C++ Compiler.

    Doch: der gcc (3.3.2) compilierts anstandslos, und Segfaults hab ich auch keine bekommen.

  • Lord Binary
    Punkte
    3.301
    Beiträge
    647
    • 6. Juni 2004 um 21:12
    • #8

    Seltsam, aber richtig, gcc 3.2 compiliert das tatsächlich.

    Hab' hier ne ältere gcc Version, und da kommt die Fehlermeldung die ich eigentlich erwartet hab: (sinngemäß) ich will x und y konstant !!!

    Wär interessant, wie das tatäschlich übersetzt wird.
    Speicher dynamisch oder statisch anglegt ?
    Egal ... hab im AUgenblick keine Lust auf Assemblercode :]

  • Georg Kraml
    Punkte
    90
    Beiträge
    18
    • 6. Juni 2004 um 21:20
    • #9
    Zitat von jeuneS2

    Doch: der gcc (3.3.2) compilierts anstandslos,

    Ihr habt beide halb recht - in C89/90 ist sowas absolut verboten, in C99 ist es unter bestimmten Umständen erlaubt. Ältere oder auf Wachsamkeit konfigurierte gccs melden "y.c:4: error: ISO C90 forbids variable-size array `positions'".


    Zitat

    und Segfaults hab ich auch keine bekommen.

    Reines Glück. 11 MB auf dem Stack sind nicht unbedingt stabilitätsfördernd.

    Der Code von Plantschkuh! ist übrigens bis auf ein paar kosmetische Kleinigkeiten sauber.

    .

  • Maximilian Rupp 27. Dezember 2024 um 12:06

    Hat das Thema aus dem Forum Programmieren nach Entwicklung verschoben.

  1. Datenschutzerklärung
  2. Impressum