Ir ao conteúdo
  • Cadastre-se

C Falha de Segmentação utilizando ponteiro de struct


MalThas

Posts recomendados

Saudações,

 

Preciso fazer um programa que tenha uma estrutura de tamanho fixo TAM (Vetor de struct), onde cada posição apontará para uma outra estrutura auxiliar de tamanho dinâmico. O que pensei foi o seguinte:

 

#include <stdio.h> 
#include <stdlib.h>
#define TAM 10

typedef struct Aux{
    int *N;
}Aux;

typedef struct Principal{
    Aux *Prox;
}Principal;

nt Inexistente(Principal *Estrutura, int i){
    if(Estrutura[i].Prox == NULL){
        return 1;
    }else{
        return 0;
    }
}

void Inserir(Principal *Estrutura){
    int i = 0;
    int Tamanho = 0;

    printf("Digite a posicao na qual deseja inserir o elemento: ");
    scanf("%d", &i);

    if(Inexistente(Estrutura, i) == 1){
        printf("Nao existe uma estrutura auxiliar. Insira o tamanho dela: ");
        scanf("%d", &Tamanho);

        Estrutura[i].Prox -> N = (int *)malloc(Tamanho * sizeof(int)); //Erro está aqui!
    }

    printf("\nDigite o elemento a ser inserido: ");
    scanf("%d", &Estrutura[i].Prox -> N[0]);
    printf("\nDigite o elemento a ser inserido: ");
    scanf("%d", &Estrutura[i].Prox -> N[1]);
}

int main(){
    Principal Estrutura[TAM];
    int i = 0;

    for(i=0; i<TAM; i++){
        Estrutura[i].Prox = NULL;
    }

    Inserir(Estrutura);
    Inserir(Estrutura);

    printf("\n%d", Estrutura[0].Prox -> N[0]);
    printf("\n%d", Estrutura[0].Prox -> N[1]);

É nessa linha comentada do código que, aparentemente, ocorre a Falha de Segmentação. A minha ideia é que o ponteiro 'Prox' dentro de Estrutura aponte para uma struct que contenha um ponteiro de inteiros (struct Aux) que será inicializado por malloc como um vetor de tamanho definido pelo usuário.

 

Espero ter sido claro, serei grato por qualquer ajuda.

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

Faltou você inicializar o Prox

if(Inexistente(Estrutura, i) == 1){
        printf("Nao existe uma estrutura auxiliar. Insira o tamanho dela: ");
        scanf("%d", &Tamanho);
        Estrutura[i].Prox = (Aux *)malloc(sizeof(Aux)); //insira essa linha
        Estrutura[i].Prox -> N = (int *)malloc(Tamanho * sizeof(int)); //Erro está aqui!
    }

 

  • Obrigado 1
Link para o comentário
Compartilhar em outros sites

Muitíssimo obrigado, amigo! O problema foi resolvido e eu aprecio a clareza na explicação.

 

Entretanto, estou em outro empasse (provavelmente mais uma falha de ponteiros). Necessito imprimir os valores dessa mesma estrutura e estou recebendo falha de segmentação:

 

void Imprimir(Principal *Estrutura){
    int i = 0;
    int j = 0;

    while(i<TAM){
        printf("\n--------------------------\n");
        printf("Posicao %d da estrutura Principal\n", i);

        printf("Elementos: ");
        while(Estrutura[i].Prox -> N != NULL){
            printf("%d, ", Estrutura[i].Prox -> N[j]);
            j++;
        }
        i++;
    }
}

 

Link para o comentário
Compartilhar em outros sites

Isso é um pouco mais complicado, pois o tamanho do array N vai variar. Eu sugiro a seguinte solução: armazenar o tamanho que o usuário entra. Altere a estrutura Aux para acrescentar a variável tamanho:

typedef struct Aux{
    int *N;
	unsigned int tamanho;    
}Aux

if(Inexistente(Estrutura, i) == 1){
        printf("Nao existe uma estrutura auxiliar. Insira o tamanho dela: ");
        scanf("%d", &Tamanho);
        Estrutura[i].Prox = (Aux *)malloc(sizeof(Aux));
		Estrutura[i].Prox->tamanho = Tamanho;// insira essa linha para salvar o tamanho
        Estrutura[i].Prox -> N = (int *)malloc(Tamanho * sizeof(int)); 
    }

Para imprimir:

void Imprimir(Principal *Estrutura){
    int i = 0;
    int j = 0;

    while(i<TAM){
        printf("\n--------------------------\n");
        printf("Posicao %d da estrutura Principal\n", i);

        printf("Elementos: ");
        if (Estrutura[i].Prox != NULL){
            for (j = 0; j < Estrutura[i].Prox->tamanho; j++) {
              printf("%d, ", Estrutura[i].Prox -> N[j]);
            }
        }
        i++;
    }
}

Veja se funcionar (pode ter algum erro de sintaxe, pois não pude testar);

  • Obrigado 1
Link para o comentário
Compartilhar em outros sites

Obrigado, problema resolvido. Mas aqui estou eu tendo que te incomodar novamente. Desenvolvi o código e estou quase acabando o trabalho, mas ao executar as operações 'Inserir, Aumentar, Inserir', o programa fica esperando infinitamente por uma entrada. Segue imagem do erro:

 

 1867886183_Capturadetelade2019-03-0802-07-27.thumb.png.01f62f3cfa9d0258deb349e292342804.png

 

Eu realmente não faço ideia do porque esse scanf está dando problema. O código atualmente está assim e a linha problemática está comentada:

 

#include <stdio.h> 
#include <stdlib.h>
#define TAM 10

typedef struct Aux{
    int *N;
    unsigned int Sizes;
}Aux;

typedef struct Principal{
    Aux *Prox;
}Principal;


int menu();

int Inexistente(Principal *Estrutura, int i){
    if(Estrutura[i].Prox == NULL){
        return 1;
    }else{
        return 0;
    }
}

void Imprimir(Principal *Estrutura){
    int i = 0;
    int j = 0;
    int Temp = 0;

    while(i<TAM){
        printf("\n--------------------------\n");
        printf("Posicao %d da estrutura Principal\n", i);

        printf("Elementos: ");

        if(Estrutura[i].Prox != NULL){
            for (j = 0; j < Estrutura[i].Prox->Sizes; j++) {
                printf("%d, ", Estrutura[i].Prox -> N[j]);
            }
        }
        i++;
    }
    printf("\n");
}

int Cheio(Principal *Estrutura, int i){
   int temp = 0;

   while(temp < Estrutura[i].Prox -> Sizes){
    if(Estrutura[i].Prox -> N[temp] != 0){
        temp++;
    }
   }

   if(temp == Estrutura[i].Prox -> Sizes){
    return 1;
   }else{
    return 0;
   }
}

void Inserir(Principal *Estrutura){
    int i = 0;
    int Tamanho = 0;
    int j = 0;
    int x = 0;

    printf("Digite a posicao na qual deseja inserir o elemento: ");
    scanf("%d", &i);

    if(Inexistente(Estrutura, i) == 1){
        printf("Nao existe uma estrutura auxiliar. Insira o tamanho dela: ");
        scanf("%d", &Tamanho); //////// É aqui que o erro acontece. Inserir -> Aumentar -> Inserir, e o loop começa.

        Estrutura[i].Prox = (Aux *)malloc(sizeof(Aux));
        Estrutura[i].Prox -> N = (int *)malloc(Tamanho * sizeof(int));
        Estrutura[i].Prox -> Sizes = Tamanho;

        for(x = 0; x < Tamanho; x++){
            Estrutura[i].Prox -> N[x] = 0;
        }
    }

    else if(Cheio(Estrutura, i) == 1){
        printf("Estrutura auxiliar cheia!\n");
        return;
    }

    while(j < Estrutura[i].Prox -> Sizes){
        if(Estrutura[i].Prox -> N[j] == 0){
            printf("\nDigite o elemento a ser inserido: ");
            scanf("%d", &Estrutura[i].Prox -> N[j]);
        }
        j++;
    }
}

void Aumentar(Principal *Estrutura){
    int NewSize = 0;
    int i = 0;
    int temp = 1;

    printf("\nInsira a posicao que deseja aumentar: ");
    scanf("%d", &i);

    if(Inexistente(Estrutura, i) == 1){
        printf("\nEstrutura Auxiliar Inexistente!\n");  
    }

    printf("TAMANHO %d\n",Estrutura[i].Prox -> Sizes );

    printf("\nInsira o novo numero de posições a ser adicionado na estrutura auxiliar: ");
    scanf("%d", &NewSize);

    while(temp <= NewSize){
        Estrutura[i].Prox -> N = (int *)realloc(Estrutura[i].Prox -> N, temp * sizeof(int));
        temp++;
        Estrutura[i].Prox -> Sizes++;
    }
    printf("TAMANHO %d\n",Estrutura[i].Prox -> Sizes );
}

int menu(){
    int op;
    printf("\n--------------------------\n");
    printf("\nDigite a opção desejada\n");
    printf("0 - Sair\n");
    printf("1 - Inserir Elemento\n");
    printf("2 - Listar\n");
    printf("3 - Listar Ordenadamente cada estrutura auxiliar\n");
    printf("4 - Listar Ordenadamente todos os numeros\n");
    printf("5 - Excluir um elemento\n");
    printf("6 - Aumentar tamanho da Estrutura Auxiliar\n");
    scanf("%d", &op);
    return op;
}

int main(){
    Aux *Auxiliar = NULL;
    Principal Estrutura[TAM];
    int op;
    int sair = 0, i = 0;

    for(i=0; i<TAM; i++){
        Estrutura[i].Prox = NULL;
    }   

    while (!sair){
        op = menu();
        switch (op){
            
            case 0:    
                sair = 1;
                break;
            
            case 1:
                Inserir(Estrutura);
                break;
            
            case 2:
                Imprimir(Estrutura);
                break;

            case 3: break;

            case 4: break;

            case 5: break;

            case 6:
                Aumentar(Estrutura);
                break;

            default:
                printf("Opcao Inválida\n");         
        } 
    }
    
    return 0;
}

 

Link para o comentário
Compartilhar em outros sites

Na função "Aumentar" insira um "return" na posição indicada abaixo. Também a função não tem necessidade de se usar um "while" para aumentar a estrutura, basta realocar a memória uma única vez. Acredito que agora irá funcionar:

void Aumentar(Principal *Estrutura){
    int NewSize = 0;
    int i = 0;
    int temp = 1;

    printf("\nInsira a posicao que deseja aumentar: ");
    scanf("%d", &i);

    if(Inexistente(Estrutura, i) == 1){
        printf("\nEstrutura Auxiliar Inexistente!\n");  
		return; //insira essa linha, pois se a estrutura não existe não tem sentido em continuar o restdo do código
    }

    printf("TAMANHO %d\n",Estrutura[i].Prox -> Sizes );

    printf("\nInsira o novo numero de posições a ser adicionado na estrutura auxiliar: ");
    scanf("%d", &NewSize);
	Estrutura[i].Prox -> Sizes+= NewSize;
	Estrutura[i].Prox -> N = (int *)realloc(Estrutura[i].Prox -> N, Estrutura[i].Prox -> Sizes * sizeof(int));
    
    printf("TAMANHO %d\n",Estrutura[i].Prox -> Sizes );
}

Por fim, você tem que liberar a memória alocada no final, pois o "c" não faz isso automaticamente. você faz isso com "free".

 

  • Obrigado 1
Link para o comentário
Compartilhar em outros sites

3 minutos atrás, MalThas disse:

É, amigo, não funcionou. Ainda está esperando uma input que não existe. E quando você diz "liberar a memória alocada no final", você está dizendo inserir um free no fim do programa, não é?

Sim, isso mesmo. Testei neste compilador online https://www.onlinegdb.com/online_c++_compiler, com as alterações que propus, e acredito que funcionou:

--------------------------

Digite a opção desejada
0 - Sair
1 - Inserir Elemento
2 - Listar
3 - Listar Ordenadamente cada estrutura auxiliar
4 - Listar Ordenadamente todos os numeros
5 - Excluir um elemento
6 - Aumentar tamanho da Estrutura Auxiliar
1
Digite a posicao na qual deseja inserir o elemento: 0
Nao existe uma estrutura auxiliar. Insira o tamanho dela: 3

Digite o elemento a ser inserido: 1

Digite o elemento a ser inserido: 2

Digite o elemento a ser inserido: 3

--------------------------

Digite a opção desejada
0 - Sair
1 - Inserir Elemento
2 - Listar
3 - Listar Ordenadamente cada estrutura auxiliar
4 - Listar Ordenadamente todos os numeros
5 - Excluir um elemento
6 - Aumentar tamanho da Estrutura Auxiliar
6

Insira a posicao que deseja aumentar: 0
TAMANHO 3

Insira o novo numero de posições a ser adicionado na estrutura auxiliar: 2
TAMANHO 5

--------------------------

Digite a opção desejada
0 - Sair
1 - Inserir Elemento
2 - Listar
3 - Listar Ordenadamente cada estrutura auxiliar
4 - Listar Ordenadamente todos os numeros
5 - Excluir um elemento
6 - Aumentar tamanho da Estrutura Auxiliar
1
Digite a posicao na qual deseja inserir o elemento: 1
Nao existe uma estrutura auxiliar. Insira o tamanho dela: 2

Digite o elemento a ser inserido: 4

Digite o elemento a ser inserido: 5

--------------------------

Digite a opção desejada
0 - Sair
1 - Inserir Elemento
2 - Listar
3 - Listar Ordenadamente cada estrutura auxiliar
4 - Listar Ordenadamente todos os numeros
5 - Excluir um elemento
6 - Aumentar tamanho da Estrutura Auxiliar
2

--------------------------
Posicao 0 da estrutura Principal
Elementos: 1, 2, 3, 0, 0, 
--------------------------
Posicao 1 da estrutura Principal
Elementos: 4, 5, 
--------------------------
Posicao 2 da estrutura Principal
Elementos: 
--------------------------
Posicao 3 da estrutura Principal
Elementos: 
--------------------------
Posicao 4 da estrutura Principal
Elementos: 
--------------------------
Posicao 5 da estrutura Principal
Elementos: 
--------------------------
Posicao 6 da estrutura Principal
Elementos: 
--------------------------
Posicao 7 da estrutura Principal
Elementos: 
--------------------------
Posicao 8 da estrutura Principal
Elementos: 
--------------------------
Posicao 9 da estrutura Principal
Elementos: 

--------------------------

Digite a opção desejada
0 - Sair
1 - Inserir Elemento
2 - Listar
3 - Listar Ordenadamente cada estrutura auxiliar
4 - Listar Ordenadamente todos os numeros
5 - Excluir um elemento
6 - Aumentar tamanho da Estrutura Auxiliar
6

Insira a posicao que deseja aumentar: 1
TAMANHO 2

Insira o novo numero de posições a ser adicionado na estrutura auxiliar: 5
TAMANHO 7

--------------------------

Digite a opção desejada
0 - Sair
1 - Inserir Elemento
2 - Listar
3 - Listar Ordenadamente cada estrutura auxiliar
4 - Listar Ordenadamente todos os numeros
5 - Excluir um elemento
6 - Aumentar tamanho da Estrutura Auxiliar
2

--------------------------
Posicao 0 da estrutura Principal
Elementos: 1, 2, 3, 0, 0, 
--------------------------
Posicao 1 da estrutura Principal
Elementos: 4, 5, 0, 0, 0, 0, 135041, 
--------------------------
Posicao 2 da estrutura Principal
Elementos: 
--------------------------
Posicao 3 da estrutura Principal
Elementos: 
--------------------------
Posicao 4 da estrutura Principal
Elementos: 
--------------------------
Posicao 5 da estrutura Principal
Elementos: 
--------------------------
Posicao 6 da estrutura Principal
Elementos: 
--------------------------
Posicao 7 da estrutura Principal
Elementos: 
--------------------------
Posicao 8 da estrutura Principal
Elementos: 
--------------------------
Posicao 9 da estrutura Principal
Elementos: 

--------------------------

Digite a opção desejada
0 - Sair
1 - Inserir Elemento
2 - Listar
3 - Listar Ordenadamente cada estrutura auxiliar
4 - Listar Ordenadamente todos os numeros
5 - Excluir um elemento
6 - Aumentar tamanho da Estrutura Auxiliar

 

  • Obrigado 1
Link para o comentário
Compartilhar em outros sites

Entendi agora, sua função CHEIO estava em um loop infinito. Testa assim agora:

int Cheio(Principal *Estrutura, int i){
   int temp = 0;

   for (int j=0; j< Estrutura[i].Prox -> Sizes; j++){ 
    if(Estrutura[i].Prox -> N[j] != 0){ 
        temp++; 
    }
   }

   if(temp == Estrutura[i].Prox -> Sizes){
    return 1;
   }else{
    return 0;
   }
}

 

  • Obrigado 1
Link para o comentário
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...

Ebook grátis: Aprenda a ler resistores e capacitores!

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!