1. Dashboard
  2. Forum
    1. Unerledigte Themen
  3. Mitglieder
    1. Letzte Aktivitäten
    2. Benutzer online
    3. Team-Mitglieder
    4. Trophäen
    5. Mitgliedersuche
  4. Tutorial Bereich
  • Anmelden
  • Registrieren
  • Suche
Dieses Thema
  • Alles
  • Dieses Thema
  • Dieses Forum
  • Seiten
  • Forum
  • Lexikon
  • 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
  • Gianna
    10
    Gianna
    Mitglied
    Reaktionen
    2
    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]

    Johanna Schmidt
    VIS1 Übungsleitung
    CG Vorlesung

  • Plantschkuh!
    24
    Plantschkuh!
    Mitglied
    Reaktionen
    163
    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.

    *plantsch*

  • Gianna
    10
    Gianna
    Mitglied
    Reaktionen
    2
    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?

    Johanna Schmidt
    VIS1 Übungsleitung
    CG Vorlesung

  • Lord Binary
    18
    Lord Binary
    Mitglied
    Reaktionen
    11
    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


    Trading for a living [equities,futures,forex]

  • Gianna
    10
    Gianna
    Mitglied
    Reaktionen
    2
    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))

    Johanna Schmidt
    VIS1 Übungsleitung
    CG Vorlesung

  • Plantschkuh!
    24
    Plantschkuh!
    Mitglied
    Reaktionen
    163
    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 :winking_face:

    *plantsch*

  • jeuneS2
    11
    jeuneS2
    Mitglied
    Reaktionen
    17
    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.

    Why bother spending time reading up on things? Everybody's an authority, in a free land.

  • Lord Binary
    18
    Lord Binary
    Mitglied
    Reaktionen
    11
    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 :]


    Trading for a living [equities,futures,forex]

  • Georg Kraml
    3
    Georg Kraml
    Böser Wolf
    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.

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!

Benutzerkonto erstellen Anmelden

Benutzer online in diesem Thema

  • 1 Besucher

Rechtliches

Impressum

Datenschutzerklärung