Segmentation failure (recorded core image)

Asked

Viewed 928 times

1

I’m making a program for a simple purpose: Take a sentence and turn it into a version of it with the characters of each word isolated to the contrary, as: "I’m in trouble" would become "uotsE moc samelborp". When compiling with gcc questao1.c -o Q1 -g, write gdb . /Q1 and run, it shows the following error:

Program received signal SIGSEGV, Segmentation fault.
0x0000555555554836 in pilha_push (p=0x555555757010, v=101 'e') at questao1.c:23
23  p->c[p->topo] = v;

I have looked in many places and nothing has been useful to me. Follows the code:

#include<stdlib.h>
#include<stdio.h>
int N = 50;

typedef struct pilha{
        char *c;
        int topo;
}Pilha;

Pilha* pilha_cria(void)
{
Pilha* p = (Pilha*) malloc(sizeof(Pilha));
p->topo = 0;
return p;
}

void pilha_push (Pilha* p, char v)
{
if (p->topo == N) {
printf("Capacidade da pilha estourou.\n");
exit(1);
}
p->c[p->topo] = v;
p->topo++;
}

void inverte_palavra(char c[], int n){
      char c1[n];
      int i=0;
      for(i=n-1;i>=0;i--){
                          c1[i] = c[n-i];
      }
      i=0;
      for(i=0;i<n;i++){
                   printf("%c", c1[n]);
  }
}
void zerar_char(char c[], int n){
 char c1[n];
 c = c1;
}
void inverter_pilha(Pilha *p){
 int n = 0;
 int i=0;
 char c1[p->topo];
 for(i = 0; i<p->topo;i++){
       if(p->c[i] != ' '){
               c1[i] = p->c[i];
               n++;
       }else{
                   inverte_palavra(c1, n);
                   n = 0;
                   zerar_char(c1, p->topo);
       }
 }
}

int main(){

Pilha *p;
p = pilha_cria();
pilha_push(p, 'e');
pilha_push(p, 's');
pilha_push(p, 't');
pilha_push(p, 'a');
pilha_push(p, ' ');
pilha_push(p, 'p');
pilha_push(p, 'r');
pilha_push(p, 'o');
pilha_push(p, 'v');
pilha_push(p, 'a');
inverter_pilha(p);
}

2 answers

2


Like the pointer p->c points to an undefined place when trying to record the data v in position p->topo, your program accessed a "prohibited" memory position and received a "Segmentation Failure" signal".

In function pilha_cria(), you allocated a Pilha, but did not allocate memory to accommodate your items at p->c.

Here is an example (tested and improved) of how to make your program work properly:

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

typedef struct pilha {
    char *c;
    int tam;
    int topo;
} Pilha;

Pilha* pilha_cria(int tam)
{
    Pilha * p = (Pilha*) calloc( 1, sizeof(Pilha) );
    p->c = (char*) calloc( tam, sizeof(char) );
    p->topo = 0;
    p->tam = tam;
    return p;
}

void pilha_destruir(Pilha*p)
{
    free(p->c);
    free(p);
}

void pilha_push(Pilha* p, char v){
    if (p->topo < p->tam){
        p->c[ p->topo++ ] = v;
    }
}

void inverter_pilha(Pilha *p){
    int i = 0;
    int n = p->topo;
    for( i=0; i<n/2; i++){
        char aux = p->c[i];
        p->c[i] = p->c[n-1-i];
        p->c[n-1-i] = aux;
    }
}

void exibir_pilha(Pilha *p){
    int i=0;
    for(i=p->topo-1; i>=0; i--){
        printf("    [%d] %c\n", i, p->c[i]);
    }
}


int main( void ){
    Pilha * p = NULL;

    p = pilha_cria( 5 );

    pilha_push(p, 'A');
    pilha_push(p, 'E');
    pilha_push(p, 'I');
    pilha_push(p, 'O');
    pilha_push(p, 'U');

    printf("PILHA ORIGINAL:\n");
    exibir_pilha(p);

    inverter_pilha( p );

    printf("PILHA INVERTIDA:\n");
    exibir_pilha(p);

    pilha_destruir( p );
    return 0;
}

Exit:

PILHA ORIGINAL:
    [4] U
    [3] O
    [2] I
    [1] E
    [0] A
PILHA INVERTIDA:
    [4] A
    [3] E
    [2] I
    [1] O
    [0] U
  • Thank you for your help, it was literally my solution. I don’t think I was very clear about the purpose of the program which may have caused you a confusion: The idea was not to reverse the whole stack but to invert the isolated words from the stack. So I took his program and, based on it, I added what was necessary for this goal: https://pastebin.com/tMxGncB7 (I still don’t know how to move very well with stack overflow, so I went pro Pastebin because it is simpler to put whole codes)

1

You forgot to allocate p->c in the creative function of Pilhas, the pilha_cria. Since this value is coming from a crudely allocated memory area, it will necessarily have memory junk. Occasionally this trash can hypothetically speaking point to a place that does not burst the exception of segmentation failure, but this is luck.

To fix, you can set in the structure char c[50] OR EXCLUSIVE then, if you insist on using dynamic memory for this section, at the end of pilha_cria, call for p->c = (char*) calloc(sizeof(char), N);

do not mix up both approaches above; they solve the problem in distinct and immiscible ways, trying to use them together will generate compilation error

The calloc will allocate the required space with all zeroed bytes, so I believe this avoids some unwanted dirt on p->c that can generate some difficult to catch bug.


Taking advantage, its function zerar_char does not have the desired side effect, being really innocuous. The way you are storing the word to be reversed is also strange, even wrong. Try to reset the work index of c1 all life you reach a point of inversion. Note also that if the last letter is not space, there will be no inversion of the last word, then it would be appropriate to detect cases like this and do the inversion at the end of the last word stored in p->c.

Taking advantage once again, the structure you are creating is not exactly a stack: it does not follow the LIFO principle, but seems to follow FIFO (queue property). Avoid using names that name certain concepts in situations other than the original concepts, this will generate confusion and difficulty reading.


Another interesting point: it is more common in declare these numerical magic constants as their N as pre-processing directives; for example, the following could be used instead of int N = 50;:

#define SIZE_MAX_PILHA 50

Each approach has its features, it’s up to you, as a programmer, to distinguish. How your number N seemed a constant magic, I suggested leaving this example of good practice (to @Maniero B-]’s despair) so that you can reflect on the subject in the future.

  • When implementing what was recommended, the following errors appeared: questao1.c: In Function ľpilha_cria': questao1.c:13:6: error: assignment to Expression with array type p->c = (char*) calloc(sizeof(char), N); questao1.c: In Function ľpilha_push': questao1.c:24:15: Warning: assignment makes Pointer from integer without a cast [-Wint-Conversion] p->c[p->topo] = v; questao1.c:49:26: Warning: assignment makes integer from Pointer without a cast [-Wint-Conversion] C1[i] = p->c[i];

  • this error has not been sent here: questao1.c: In Function 'inverr_stack': questao1.c:48:23: Warning: comparison between Pointer and integer if(p->c[i] != ' ' && i<p->top-1){ ^~

  • And thanks for the tips, they were very useful to improve my understanding. On the stack look like a queue: this was probably because I did not implement an element removal method, but this was because the problem did not require a removal policy even.

  • You changed the structure And called the calloc?

  • On the subject of naming pedanticism, I do not think this is the best place to discuss, I think perhaps it would be better to chat another day.

  • @J.Gaidzinski changed my answer to make it clear that: or exclusive uses the alternative of char c[50], or exclusive uses the alternative of calloc

Show 1 more comment

Browser other questions tagged

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