Error Segmentation fault without indentification

Asked

Viewed 289 times

1

Hello, my friends!

I am creating a program that will read a text. This text should be allocated one line at a time (up to 75 characters per line).

The program receives, in the input , the user’s text until the string "the end!" is typed.

However when running the program, I am having the error: Segmentation fault (core dumped). (Detail: This error is common to me, and several times I have tried to solve it, but without success). Please tell us why this error happens, not only in this code but also its common causes.)

Later, I will use the stringUpper function to capitalize my text.

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#define MAX_CHAR 75

const char THE_END[] = "the end!";
void stringUpper(char*, int);

void main() {
    char **texto;
    int i = 0;
    int j;
    texto = NULL;
    for( ; ; ) {
        texto = (char**)realloc(texto,(i+1)*sizeof(char*));
        texto[i] = (char*)malloc(MAX_CHAR*sizeof(char));
        fgets(texto[i],MAX_CHAR,stdin);
        texto[strlen(texto[i]-1)] = '\0'; // troca o '\n' (úlimo dígito da string) pelo terminador nulo
        if(strcmp(THE_END,texto[i]) == 0) break;
        i++;
    }

    for(j = 0; j < i; i++) {
        free(texto[j]);
    }

    free(texto);






}

void stringUpper(char *s, int tam) {
    int i = 0;
    for(i = 0; i < tam; i++) {
        s[i] = toupper(s[i]);
    }
}

3 answers

1

There are some problems in your program. strcmp, in the case of equality, returns 0, not the other way around. In addition, the fgets has the drawback of not eliminating the \n at the end of the input. You can fix this by replacing it with a \0 or by putting it in the comparison. A possible solution then would be:

if (strcmp("the end!\n", texto[i]) == 0) break;

Also, don’t forget that you need to give free not only at the address of texto, but on each of the lines as well.

I couldn’t recreate your Segfault, but the problem could be in this realloc which is called when the pointer texto initially contains trash. Try making a malloc for him before.

  • Hello, Emoon! I made the necessary modifications. However, with regard to the "Segmentation fault", it continues to appear even if I do a malloc before.

  • You could turn the gdb to find out exactly what line this Segfault is going on?

1


Friend Emoon found the first part of the problem in his answer, that the fgets puts a \n at the end of the string read and need to give free in each of the strings allocated.

As for this \n, the solution would be to replace it with \0 and that’s what you did. Or rather, that’s what you tried to make!

You made this code to replace the \n for \0:

texto[strlen(texto[i]-1)] = '\0';

That is wrong. That would be right:

texto[i][strlen(texto[i]) - 1] = '\0';

Then, at the time of shifting the strings, see your loop:

for(j = 0; j < i; i++)

That tie is wrong! It was meant to be j++ instead of i++.

Fixing these little problems, the code worked for me as expected.

  • You’re right. Worst of all is that I made these 2 mistakes out of sheer lack of attention, but when it came to (trying) to correct them, I couldn’t figure it out. Do you think this is bad for a programmer? Do you think it could hurt my career or not? (You leave your reply here. I thank you in advance) :)

  • Now, it’s all working perfectly.

  • @L.Pedro If the answer served, don’t forget to click the green to mark this answer as correct/accepted.

  • That’s what I was going to comment on too, he was assigning \0 a pointer, that is, the same as NULL. + 1 to complement the answer

0

I finished the code. It’s like this now:

 #include <stdio.h> 
 #include <stdlib.h>
 #include <ctype.h>
 #include <string.h>
 #define MAX_CHAR 75

const char THE_END[] = "the end!";
void stringUpper(char*, int);
void clearBuffer();
void textUpper(char**,int);
void printText(char**,int);
char **desalocaTexto(char**,int);

void main() {
    char **texto;
    int i = 0;
    int j;
    texto = NULL;
    for( ; ; ) {
        texto = (char**)realloc(texto,(i+1)*sizeof(char*));
        texto[i] = (char*)malloc(MAX_CHAR*sizeof(char));
        //clearBuffer();
        fgets(texto[i],MAX_CHAR,stdin);
        texto[i][strlen(texto[i]) - 1] = '\0';// troca o '\n' (úlimo dígito da string) pelo terminador nulo

        if(strcmp(THE_END,texto[i]) == 0) break;
        i++;
    }

    textUpper(texto, i);
    printText(texto,i);

    texto = desalocaTexto(texto,i);
}

void stringUpper(char *s, int tam) {
    int i = 0;
    for(i = 0; i < tam; i++) {
        s[i] = toupper(s[i]);
    }
}


void clearBuffer() {
    char c;
    while((c = getchar()) != '\n' && c != EOF);

}

void textUpper(char **texto ,int tam) {
    int i;
    for(i = 0; i < tam; i++) {
        stringUpper(texto[i],MAX_CHAR);
    }
}

void printText(char **texto,int tam) {
    int i;
    for(i = 0; i < tam; i++) {
        printf("%s\n",texto[i]);
    }

}

char **desalocaTexto(char **t ,int linhas) {
    int j;
    for(j = 0; j < linhas; j++) {
        free(t[j]);
    }

    free(t);
    return NULL;
}

Guys, considering I’m a beginner, is the code well done in your opinion? How long on average can I become a C professional?

  • The code is well done and indented, only a few consistency gaps in spacing that could be corrected.

  • Now, the point is, you really Want to become a C professional? It’s good to know the basics of the language, this does not deny, but professionally you will want to work with something more robust and object-oriented. And C++ exists precisely for this, which basically contains all of C with the advantage of being a modern language and as efficient as

  • Don’t get me wrong, C even has its didactic purposes, like teaching low-level concepts like pointers and addresses, but unfortunately there is a conservatism (at least that’s what I see at my university), of professors with their heads dipped 20 years in the past, of wanting to use it for almost anything. And unfortunately we ended up mistakenly clinging to it

  • 1

    Emoon, thank you. :)

Browser other questions tagged

You are not signed in. Login or sign up in order to post.