首页 > 解决方案 > 在链表实现中调用 strcpy() 时如何解决分段错误?

问题描述

我遇到了这种结构的分段错误问题。我尝试使用strcpy将 char 值复制到列表结构但没有工作。


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

    typedef struct Elemento_FILA{
    // int cod_cliente, consumo, dia_venc, mes_venc, ano_venc;
    // float preco_un,valor_total;
    char nome_cliente[40];
    struct Elemento_FILA *proximo;
    } Elemento_Fila;

    typedef struct Fila{
    struct Elemento_FILA *inicio; 
    struct Elemento_FILA *fim; 
    } Fila;
    int escolha; 


    Fila* Criar_Fila(){

    Fila *f = (Fila*) malloc(sizeof(Fila));
    if(!f)
    exit(1);
    else {
    f->inicio = NULL; 
    f->fim = NULL; 
    }
    return f;
    }


    int Fila_Vazia(Fila *f){
    if(f==NULL) return 1; 
    if(f->inicio==NULL) return 1; 
    else return 0;
    }

    int Ler_Cod(){
    int cod;
    printf (" Digite o código para o cliente: ");
    scanf("%i",&cod);
    return cod;
    }

    char* Ler_Nome() {
    char* nome_cliente = malloc(40*sizeof(char));
    printf(" Digite o nome do cliente: ");
    scanf("%s", &nome_cliente);
    return nome_cliente;
    }

    int Ler_Consumo(){
    int consumo;
    printf (" Digite o consumo para o cliente: ");
    scanf("%i",&consumo);
    return consumo;
    }


    Elemento_Fila* Alocar(const char* nome){

    Elemento_Fila *no_fila = (Elemento_Fila*)malloc(sizeof(Elemento_Fila));

    if(!no_fila)
    exit(1);
    else{

    strcpy(no_fila->nome_cliente,nome); 


    return no_fila;
    }
    }

    void Enfileirar(Fila *f){
    Elemento_Fila *no_fila = Alocar(Ler_Nome());
    if(!no_fila) 
    exit(1);
    if(f->fim == NULL) 
    f->inicio = no_fila;
    else 
    f->fim->proximo = no_fila; 
    f->fim = no_fila; 
    }

    int Desenfileirar(Fila *f){

    if(Fila_Vazia(f)) return 0;

    Elemento_Fila *no_fila = f->inicio;

    f->inicio = f->inicio->proximo;

    if(f->inicio==NULL)
    f->fim = NULL;

    free(no_fila);
    return 1;
    }

    void Exibir_Fila(Fila *f){

    if(Fila_Vazia(f)){
    printf (" Fila Vazia!\n");
    printf ("\n Fila End. Inicio %p: ", f->inicio);
    printf ("\n Fila End. Fim %p: ", f->fim);
    return ;
    }

    Elemento_Fila *aux = f->inicio;
    printf ("\n Fila Atual: ");
    printf ("\n Fila End. Inicio %p: ", f->inicio);
    printf ("\n Fila End. Fim %p: ", f->fim);
    printf ("\n");

    while(aux!=NULL){
    printf ("\n\t  Nome: %s  \tEndereco: %p ==> %p", aux->nome_cliente, aux, aux->proximo);

    aux = aux->proximo;
    }
    printf ("\n");
    }

    void opcoes(int escolha, Fila *f){
    switch(escolha){
    case 1:
    Enfileirar(f);
    Exibir_Fila(f);
    break;
    case 2:
    Desenfileirar(f);
    Exibir_Fila(f);
    break;
    default:
    if (escolha!=0) printf (" Opção Inválida!\n");
    }
    }


    int menu(){
    printf ("\n Opções da Fila;\n");
    printf (" 0 Sair;\n");
    printf (" 1 Inserir na Fila;\n");
    printf (" 2 Retirar da Fila;\n");
    printf (" Escolha: ");
    scanf("%i", &escolha);
    return escolha;
    }

    int main (void){

    Fila *f = Criar_Fila();
    do{
    escolha = menu();
    opcoes(escolha,f);
    }while(escolha);
    return 0;
    }

标签: c

解决方案


您在这里有几个问题,但最关键的是您在Ler_Nome()下面的函数中所做的事情:

char Ler_Nome() {
  char nome_cliente[40];
  printf(" Digite o nome do cliente: ");
  scanf("%s", &nome_cliente);
  return nome_cliente;
}

Elemento_Fila *Alocar(const char *nome) {
    ....
    strcpy(no_fila->nome_cliente, nome);
}

您正在返回一个指针,nome该指针是函数中的局部变量Ler_Nome(),在运行时当控制到达返回时,所有函数局部变量都被释放。您正在返回一个指向不是您的变量的指针!因此操作系统通过投掷向你大喊大叫segmentation fault

然后您试图在导致灾难的函数中调用strcpy该释放局部变量(nome_client) !Alocar(...)尽管如此,这不是你做的事情C甚至没有调用bad函数的方式Ler_Nome()

记住

  1. 如果你想从函数返回指针,它必须在堆上分配!
  2. 如果你想要这个指针,那么你需要调用函数来调用它并获取它的返回值(nome_client在你的情况下是指针)
  3. 始终检查malloc()返回值!你没有检查pint整数指针!我不知道为什么你分配了一个整数指针(或一个整数的数组),而你在函数中根本没有使用它Alocar(...),然后你退出函数而不释放它(通过调用free()函数)??!!当您尝试调用时,这将导致运行时内存泄漏Alocar(...)
  4. 规则 4:您需要确保*alloc()必须正确管理和释放所有堆分配的缓冲区(通过调用 family 接收的缓冲区)!

推荐阅读