c - 在链表实现中调用 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;
}
解决方案
您在这里有几个问题,但最关键的是您在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()
。
记住
- 如果你想从函数返回指针,它必须在堆上分配!
- 如果你想要这个指针,那么你需要调用函数来调用它并获取它的返回值(
nome_client
在你的情况下是指针) - 始终检查
malloc()
返回值!你没有检查pint
整数指针!我不知道为什么你分配了一个整数指针(或一个整数的数组),而你在函数中根本没有使用它Alocar(...)
,然后你退出函数而不释放它(通过调用free()
函数)??!!当您尝试调用时,这将导致运行时内存泄漏Alocar(...)
- 规则 4:您需要确保
*alloc()
必须正确管理和释放所有堆分配的缓冲区(通过调用 family 接收的缓冲区)!
推荐阅读
- wkwebview - iOS 14 上的 WKWebView 仅在显着延迟后加载内容
- javascript - AWS IoT Core - 如何在连接丢失后启用无限重新连接 (MQTT)
- amazon-web-services - 如何从 S3 存储桶下载文件?
- image-processing - 如何计算物体和相机之间的距离,知道图像中物体占据的像素
- java - 如何在终端中使用“-tokens”打印令牌?
- c# - 切换按钮的 WPF 样式为雪佛龙 - 如何删除烦人的细线
- python - How can I correctly include a path dependency in pyproject.toml?
- hyperledger-fabric - Hyperledger fabric 1.4 Error on Instantiate chaincode
- java-7 - DCEVM+HotSwap Agent with JBoss EAP 6 & JDK 7
- reactjs - Demo Bug: why do mouse events in React fail on children?