Targeting failure (recorded core image)

1

I'm doing a program for a simple purpose: Take a phrase and turn it into a version of it with the characters of each word isolated to the contrary, like: "I'm in trouble" would turn "uotsE moc samelborp". When compiling with gcc questao1.c -o q1 -g, writing gdb ./q1 and giving run, it displays 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. Here is 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);
}
    
asked by anonymous 25.09.2017 / 04:24

2 answers

2

As the p->c pointer points to an undefined location, when it attempted to write the v data to the p->topo position, its program accessed a "forbidden" memory location and received a "Target Failed" signal.

In function pilha_cria() , you have allocated a Pilha , but have not allocated memory to accommodate your items in the p->c address.

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;
}

Output:

PILHA ORIGINAL:
    [4] U
    [3] O
    [2] I
    [1] E
    [0] A
PILHA INVERTIDA:
    [4] A
    [3] E
    [2] I
    [1] O
    [0] U
    
25.09.2017 / 15:20
1

You forgot to allocate p->c to the creative function of Pilha s, pilha_cria . Since this value is coming from a crudely allocated memory area, it will necessarily have memory garbage. Occasionally this junk can hypothetically point you to a place that does not pop the segmentation fault exception, but that's lucky.

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

  

Do not mix both approaches above; they solve the problem in different and immiscible ways, trying to use them together will generate compile error

The calloc will allocate the necessary space with the bytes all zeroed, so I think this will avoid some unwanted dirt in p->c which can generate a difficult capture bug.

Enjoying, its zerar_char function does not have the desired side effect, being really harmless. The way you're storing the word being reversed is also weird, even wrong. Try to clear the% of work% index of life every time you reach a point of inversion. Note also that if the last letter is not space, the last word will not be inverted, so it would be appropriate to detect cases like this and make the inversion at the end of the last word stored in c1 .

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

Another interesting point: declare these numeric magic constants such as p->c as preprocessing directives; for example, you could use the following instead of N :

#define SIZE_MAX_PILHA 50

Each approach has its characteristics, it is up to you, as a programmer, to distinguish. Since your %% of% seemed like a magic constant, I suggested leaving this example of good practice     

25.09.2017 / 04:33