2

i'm trying to read values from a .csv file and write them in another .txt file. But when i'm trying to pass the values it creates a Segmentation fault.

My first program, which filters the needed values from the .csv file:

int main(int argc, char **argv) {
    if (argc < 3) {
        printf("Aufruf: %s <anzahl> <bundesland>\n", argv[0]);
        printf("Beispiel: %s 100 Bayern\n", argv[0]);
        printf("Klein-/Großschreibung beachten!\n");
        exit(1);
    }
    int anzahl = atoi(argv[1]);
    char *bundesland = argv[2];

    // Statisch allokierter Speicher
    char staedte[MAX_LAENGE_ARR][MAX_LAENGE_STR];
    char laender[MAX_LAENGE_ARR][MAX_LAENGE_STR];
    int bewohner[MAX_LAENGE_ARR];

    int len = read_file("staedte.csv", staedte, laender, bewohner);

    // Hier implementieren
    char** result = malloc(MAX_LAENGE_ARR * sizeof(char *));
    if (result == NULL) {
        perror("malloc failed while allocating memory");
        exit(1);
        } 
    for (int i = 0; i < len; i++) {
        if (strcmp(bundesland, laender[i]) == 0 && *bewohner > anzahl) {
            result[i] = malloc(MAX_LAENGE_STR * sizeof(char *));
            if (result == NULL) {
                perror("malloc failed while allocating memory");
                exit(1);
            }
            snprintf(result[i], MAX_LAENGE_STR, "Die Stadt %s hat %d Einwohner.", staedte[i], bewohner[i]);
            write_file(&result[i], len);
            free(result[i]);
        }
    } 

    // Mithilfe von write_file(...) soll das Ergebnis in die "resultat.txt"
    // geschrieben werden. 
    // Dynamisch allozierter Speicher muss hier freigegeben werden.
}

And the faulting part of my second program, which should write the handed values from the first program into a .txt file:

int MAX_LAENGE_STR = 255;
int MAX_LAENGE_ARR = 100;

void write_file(char *result[], int len) {
    FILE *fp = fopen("resultat.txt", "w");
    if (fp == NULL){
        perror("resultat.txt");
        exit(1);
    }
    for (int i=0; i<len; i++) {
        printf("<write_file> loop[%d]: %s\n", i, result[i]);
        fprintf(fp, "%p\n", result[i]);
    }
    fclose(fp);
}

It creates a Segmentation fault in the 11th loop, in the write_file(), and i can't figure out why. In valgrind it's: "Invalid read size of 1".

4
  • Isn't result[i] a char*. You don't need to pass its address to write_file, just pass it directly. Also, instead of allocating MAX*sizeof(char*) when creating buffer for a string, use MAX*sizeof(char). Commented Oct 30, 2017 at 7:31
  • Also what is *bewohner > anzahl? *bewohner is the first element of your int array bewohner so same as bewohner[0]. Is that really what you want to compare? Maybe bewohner[i]but I don't know your logic here. Commented Oct 30, 2017 at 7:57
  • *bewohner is one of the values in my .csv file. With this comparison i want to compare an input to the contents of my .csv file. This part is working perfectly fine, and i'm able to run my program perfectly fine with just: printf("%s", result[i]);. But when trying to hand over the values to the second program and write those values into a txt file it crashes with the segmentation fault. And i'm not allowed to change the second program due to my prof, because thats my limitation. Commented Oct 30, 2017 at 8:05
  • Please use English-looking identifiers and messages. provide some minimal reproducible example. Compile with all warnings and debug info : gcc -Wall -Wextra -g with GCC. Improve your code to get no warnings. Use the debugger gdb Commented Oct 30, 2017 at 8:30

1 Answer 1

2
  1. result[i] = malloc(MAX_LAENGE_STR * sizeof(char *));

should be

result[i] = malloc(MAX_LAENGE_STR * sizeof(char));

sizeof(char) is by definition all the time 1, even if char is represented on more than 8 bits, which is the minimal required by the definition of C. So you can avoid writing it here.


  1. write_file(&result[i], len);

should be

write_file(result[i], length(result[i]) );

as you allocated MAX_LAENGE_STR for result[i]

and change the signature of write_file to

void write_file(char *result, int len)

as you want to pass a single string as parameter.


  1. printf("<write_file> loop[%d]: %s\n", i, result[i]);

should be

printf("<write_file> loop[%d]: %c\n", i, result[i]);

because you want to print the ith char in result, all the string once.


  1. fprintf(fp, "%p\n", result[i]);

should be

fprintf(fp, "%c\n", result[i]);

as result[i] is char, not pointer.

There are other things to say, first correct these ones.

Sign up to request clarification or add additional context in comments.

4 Comments

when i'm removing the '&' from the result. i'm getting a compiler warning, that i'm passing an incompatible pointer type. And the fprintf() cannot be changed by me, thats a regulation.
write_file should take a char* or char x[]; not char* x[] as that is an array of strings.
@ChristianSteuer yes, you need to change the signature of write_file as well.
sizeof(char) is always 1. No need to write that.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.