2016-10-11 9 views
3

Ich habe jetzt seit ein paar Stunden mit diesem Problem zu kämpfen, und ich bin ratlos, was passiert. Dies ist der Code für programm.c:Segmentierungsfehler beim Indexieren eines "mallocced" Arrays

#include <stdio.h> 
#include <stdlib.h> 
#include <assert.h> 

#define SPACE 32 
#define INITIAL 4 

typedef struct { 
    char *town; 
    char *country; 
} town_t; 

typedef struct { 
    int num_towns, current_size; 
    town_t **towns_list; 
} index_t; 

int main(int argc, char *argv[]) { 

    index_t town_index; 
    town_index.current_size = INITIAL; 
    town_index.towns_list = malloc(town_index.current_size * sizeof(*(town_index.towns_list))); 
    assert(town_index.towns_list != NULL); 

    printf("Step: %d\n", 1); 
    town_index.towns_list[0]->town = malloc(4 * sizeof(*(town_index.towns_list[0]->town))); 
    printf("Step: %d\n", 2); 
    assert(town_index.towns_list[0]->town != NULL); 

    return 0; 
} 

Unter Linux ist dies, wie es läuft:

./program 
Step: 1 
Segmentation fault 

aber auf Windows druckt es

program.exe 
Step: 1 
Step: 2 

, wie ich erwarten würde, was wirklich nicht hilft. Für die Linux-Ausgabe wird jedoch eindeutig die erste Druckanweisung ausgeführt, aber nicht die zweite, was mich zu der Annahme verleiten würde, dass die Linie dazwischen diejenige ist, die fehlerhaft ist. Besonders denke ich, town_index.towns_list[0] tut mir Probleme, aber ich kann nicht sagen, warum.

Dies ist eine relativ komplexe Datenstruktur, vielleicht bin ich irgendwann verloren. Im Grunde genommen ist town_index eine Indexstruktur, die die aktuelle Anzahl von Städten in towns_list und current_size enthält, die den Raum widerspiegelt, der derzeit verfügbar ist, um Städte zu retten. Es enthält auch ein Array von Zeigern zu town_t s, die den Namen und das Land als Strings enthalten.

Ich habe versucht, Valgrind zu verwenden, aber es hilft nicht wirklich viel. Hier ist ein Pastebin für diejenigen, die sehen wollen.

Dies ist ein vereinfachtes Szenario von dem, was ich in einem anderen Programm erlebt habe, also keine Gedanken magische Zahlen und was nicht.

Dies ist auf VirtualBox Linux Mint 64-Bit.

Ohne Frage, wenn jemand kann: Wie bekomme ich Valgrind die präzise Linien anzuzeigen? Ich sehe das überall online, aber meine Ausgabe sagt mir nur den Ordner, in dem das Programm und die Funktion ist, was nicht viel hilft.

+1

Willkommen bei Stack Overflow! Es klingt, als müssten Sie lernen, wie Sie einen Debugger verwenden, um durch Ihren Code zu gehen. Mit einem guten Debugger können Sie Ihr Programm Zeile für Zeile ausführen und sehen, wo es von dem, was Sie erwarten, abweicht. Dies ist ein essentielles Werkzeug, wenn Sie programmieren wollen. Weiterführende Literatur: [Wie kleine Programme zu debuggen] (http://ericlippert.com/2014/03/05/how-to-debug-small-programs/). –

+0

Denken Sie, dass Sie ein Sternchen verpasst haben, wenn Sie die Größe von town.index.towns_list in der ersten malloc – Toby

+1

eine freundliche Empfehlung: Verwenden Sie nicht das Suffix '_t, um Typnamen anzugeben, da sie implizit vom Standard und explizit von der POSIX reserviert sind Standard. ([Hinweis] (https://www.gnu.org/software/libc/manual/html_node/Reserved-Names.html)) –

Antwort

4

Sie initialisierten town_index.towns_list, aber nicht town_index.towns_list[0], also town_index.towns_list[0]->town ist undefiniertes Verhalten.

Sie etwas verpasst wie

for (int i = 0; i < town_index.current_size; ++i) 
    town_index.towns_list[i] = malloc(sizeof **town_index.towns_list); 

für die zweite Dimension.

+0

Ah fantastisch, genau das, was ich brauchte, danke eine Tonne! Das hat alles klar gemacht und auch das größere Programm repariert, an dem ich gearbeitet habe :) – Arkantos

0

town_index.towns_list und town_index.towns_list[0] sind nicht gleich. Sie initialisieren town_index.towns_list aber town_index.towns_list[0] ist gleich 0. Der Absturz verursacht durch Dereferenzierung town_index.towns_list[0]

Verwandte Themen