Varför krashar programmet? (C)

Trädvy Permalänk
Medlem
Registrerad
Nov 2004

Varför krashar programmet? (C)

Hej SweC!

Mitt program krashar och efter att jag nu suttit med det ett bra tag så är min hjärna helt sönder. Hjälp mig förstå varför det krashar!

Meddelandet jag får är "Segmentation fault".

char **create_char_array(int rows, int columns) { int i; char **array; array = (char **) calloc(rows, sizeof(char)); i = 0; while(i < rows) { array[i] = (char *) calloc(columns,sizeof(char)); i++; } return array; } char **input(char **array, char * inputData, int rows, int columns) { int r, c; r = 0; while(r < rows) { c = 0; while(c < columns) { while(*inputData == ' ') { scanf("%c", inputData); } if(*inputData != '\n') { array[r][c] = *inputData; scanf("%c", inputData); } else { array[r][c] = 'q'; } c++; } r++; } return array; } int main(int argc, char **argv) { int rows, columns, r, c, counter = 5; char * inputData; char **array; rows = atoi(argv[1]); columns = atoi(argv[2]); array = create_char_array(rows, columns); printf("Insert string: "); scanf("%c", inputData); // På följande rad krashar det. array = input(array, inputData, rows, columns); ... ...

Hoppas nån kan svara på det.

Mvh D

○ Citera

Trädvy Permalänk
Medlem
Registrerad
Jun 2006

Hej!
Det första mindre felet är att:

array = (char **) calloc(rows, sizeof(char));

skall vara:

array = (char **) calloc(rows, sizeof(char*));

Men problemet att programmet krashar är att du lagrar indatan från scanf

scanf("%c", inputData);

PÅ platsen där inputData pekar. Genom att du inte har definerat inputData lagras den på platsen som inputData råkar peka till. Du måste allocera plats för datan.

T.ex:

char inputData[100]; //eller calloc ... scanf("%c", &inputData);

EDIT:
Stavar som en kratta

Varför sparar du om array?

array = input(array, inputData, rows, columns);

Då du arbetar med pekardatan behöver du inte spara om värdet. Men jag antar att det bara var i testkoden hit du gjorde det.
Du borde sätta const på array i funktionen för att förtydliga hur som helst.

char **input(char ** const array, char * inputData, int rows, int columns)

citera!

Trädvy Permalänk
Medlem
Plats
Stockholm
Registrerad
Nov 2001

Ett tips när det gäller 2D-arrayer är att allokera dem i ett chunk:

char* arr = (char*)malloc(sizeof(char)*WIDTH*HEIGHT);

och sedan indexera det

arr[x + y*WIDTH] = 12;

Det gör koden för allokering bra mycket enklare, och set/get kan abstraheras bort också om man skulle vilja. Minnet thrashas dessutom mindre, och en get/set blir bara ett pekaruppslag istället för två.

void@qnet
teeworlds, stålverk80, evil schemer, c, c++
Languages shape the way we think, or don't.

Trädvy Permalänk
Medlem
Registrerad
Nov 2004

Pejstar hela koden nu.

Hängde inte riktigt med på ditt resonemang jdv.

Dosshell: Tack för det, men nu blev det jobbigt med hur pekarna ska funka. Jag får fortfarande Segmentation fault på grund av pekarna för inputData. Tror jag.

#include <stdio.h> #include <string.h> #include <stdlib.h> char **create_char_array(int rows, int columns) { int i; char **array; array = (char **) calloc(rows, sizeof(char*)); for(i = 0 ; i < rows ; i++) { array[i] = (char *) calloc(columns,sizeof(char)); i++; } return array; } char **input(char ** const array, char * inputData, int rows, int columns) { int r, c; for(r = 0; r < rows ; r++) { for(c = 0; c < columns ; c++) { while(*inputData == ' ') { scanf("%c", inputData); } if(*inputData != '\n') { array[r][c] = *inputData; scanf("%c", inputData); } else { array[r][c] = 'q'; } } } return array; } void free_char_array(char **array, int rows) { int i; for(i = 0; i < rows ; i++) { free(array[i]); } } int main(int argc, char **argv) { int rows, columns, r, c, counter = 5; char * inputData; char **array; if(argc <= 2) { printf("Missing parameters.\nUsage: <rows> <columns>\n"); return 0; } rows = atoi(argv[1]); columns = atoi(argv[2]); array = create_char_array(rows, columns); inputData = calloc(sizeof(char) * 255); printf("Insert string: "); scanf("%c", &inputData); input(array, inputData, rows, columns); counter = 0; for(c = 0; c < columns; c++) { for(r = 0 ; r < rows ; r++) { if(counter == 5) { printf(" "); counter = 0; } printf("%c", array[r][c]); counter++; } } free_char_array(array, rows); free(inputData); printf("\n"); return 0; }

○ Citera

Trädvy Permalänk
Medlem
Registrerad
Jun 2006

inputData = (char*) calloc(255, sizeof(char));

Borde det väl vara?

Sedan har du skrivit i++ i forlopen vilket inte borde vara där:

for(i = 0 ; i < rows ; i++) { array[i] = (char *) calloc(columns,sizeof(char)); //i++; }

EDIT:
Tar mig friheten att tolka jdv. (hoppas att det är okey ). jdv menar att du kan använda en pseudo array. Sedan för att skriva och hämta data i arrayen kan du kapsla in den i en struct. Detta skulle ge en lättare kod att läsa och mindre fel i koden.

citera!

Trädvy Permalänk
Medlem
Registrerad
Nov 2004

Verkar som att problemet löst sig. Tack för hjälpen alla!

○ Citera