Memory Corruption in malloc - c
I am having problems with allocation. When I try to allocate my struct variables, it gives me the error of malloc corruption. And I am kind of new at C so, I think I need some help.
More precisely when I try to allocate in this line:
g->nos = (no_grafo **)malloc(sizeof(no_grafo*))
it gives me the error I am talking about.
There is my line error in the compiler, struct, my code, and my call code:
Program received signal SIGABRT, Aborted.
__GI_raise (sig=sig#entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
51 ../sysdeps/unix/sysv/linux/raise.c: No such file or directory.
(gdb) backtrace
#0 __GI_raise (sig=sig#entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
#1 0x00007fffff040801 in __GI_abort () at abort.c:79
#2 0x00007fffff089897 in __libc_message (action=action#entry=do_abort, fmt=fmt#entry=0x7fffff1b6b9a "%s\n")
at ../sysdeps/posix/libc_fatal.c:181
#3 0x00007fffff09090a in malloc_printerr (str=str#entry=0x7fffff1b4e0e "malloc(): memory corruption") at malloc.c:5350
#4 0x00007fffff094994 in _int_malloc (av=av#entry=0x7fffff3ebc40 <main_arena>, bytes=bytes#entry=8) at malloc.c:3738
#5 0x00007fffff0970fc in __GI___libc_malloc (bytes=8) at malloc.c:3057
#6 0x0000000000402a2c in grafo_novo ()
#7 0x0000000000402f59 in criaGrafo ()
#8 0x0000000000400ca0 in verifica_criaGrafo ()
#9 0x0000000000401a9b in main ()
struct no_grafos;
typedef struct
{
int peso_ligacao;
struct no_grafos *destino;
} ligacao;
typedef struct no_grafos
{
char *nome_user;
int tamanho;
ligacao **ligacoes;
} no_grafo;
typedef struct
{
int tamanho; /* numero de nos */
no_grafo **nos; /* vetor de nos */
} grafo;
grafo* grafo_novo()
{
grafo* g;
g = (grafo*)malloc(sizeof(grafo));
if(g == NULL){
return NULL;
}
g->nos = (no_grafo **)malloc(sizeof(no_grafo*));
if(g->nos == NULL){
return NULL;
}
g->nos = NULL;
g->tamanho = 0;
return g;
}
void grafo_apaga(grafo* g)
{
if(g == NULL)
return;
if(g->nos != NULL){
int i,j;
for (i =0; i< g->tamanho; g++){
for(j=0; j< g->nos[i]->tamanho;j++){
free(g->nos[i]->ligacoes[j]);
}
free(g->nos[i]);
}
free(g->nos);
free(g);
g = NULL;
}
return;
}
no_grafo * no_insere(grafo *g, char *user)
{
if(g == NULL || user == NULL) return NULL;
for (int i = 0; i < g->tamanho; i++){
if (strcmp(g->nos[i]->nome_user, user) == 0) return NULL;
}
no_grafo * no = (no_grafo*)malloc(sizeof(no_grafo));
if(no == NULL){
return NULL;
}
no->nome_user = (char*)calloc(strlen(user)+1,sizeof(char));
if(no->nome_user == NULL){
free(no);
no = NULL;
return NULL;
}
else{
strcpy(no->nome_user,user);
}
no->ligacoes = (ligacao**)malloc(sizeof(ligacao*));
if(no->ligacoes == NULL){
free(no->nome_user);
free(no);
no = NULL;
return NULL;
}
g->nos = (no_grafo **)realloc(g->nos, (g->tamanho + 1) * sizeof(no_grafo *));
if(g->nos == NULL){
return NULL;
}
no->tamanho = 0;
g->nos[g->tamanho] = no;
g->tamanho++;
return no;
}
int cria_ligacao(no_grafo *origem, no_grafo *destino, int peso)
{
if(origem == NULL || destino == NULL || peso < 1) return -1;
for(int i=0; i < origem->tamanho; i++){
if(origem->ligacoes[i]->destino==destino){ // ligacao já existente
return 0;
}
}
ligacao *liga = (ligacao*)malloc(sizeof(ligacao));
if(liga == NULL){
return -1;
}
liga->destino = destino;
liga->peso_ligacao = peso;
origem->ligacoes[origem->tamanho] = liga;
origem->tamanho++;
return 0;
}
no_grafo * encontra_no(grafo *g, char *nomeU)
{
if(g == NULL) return NULL;
for(int i=0; i< g->tamanho; i++){
if(strcmp(g->nos[i]->nome_user,nomeU)==0){
return g->nos[i];
}
}
return NULL;
}
grafo * criaGrafo(tabela_dispersao *td)
{
if(td == NULL){
return NULL;
}
grafo * g;
g = grafo_novo();
int n[2] = {0}, contador = 0;
while(td->elementos[contador] != NULL){
no_grafo *no_remetente = no_insere(g,td->elementos[contador]->msg->remetente);
if(no_remetente != NULL){
mensagem ** tabela = tabela_listagem(td,td->elementos[contador]->msg->remetente);
if(tabela != NULL){
while(tabela[contador] != NULL){
no_grafo *no_destinatario = no_insere(g,tabela[contador]->destinatario);
if(no_destinatario != NULL){
ligacao2(td,tabela[contador]->remetente,tabela[contador]->destinatario,n);
if(n[0] != 0 && n[0] != -1){
cria_ligacao(no_remetente,no_destinatario,n[0]);
}
}
contador++;
}
}
}
td->elementos[contador] = td->elementos[contador]->proximo;
}
return g;
}
no_grafo **lista_amigos(grafo *g, char *nomeU, int *n)
{
if(g== NULL || nomeU == NULL){
return NULL;
}
n = (int*)malloc(sizeof(int));
if(n == NULL)
return NULL;
no_grafo **lista = (no_grafo**)calloc(g->tamanho,sizeof(no_grafo*));
if(lista == NULL) return NULL;
int contador=0;
for(int i = 0; i < g->tamanho;i++){
if(strcmp(g->nos[i]->nome_user,nomeU) == 0){
for(int j = 0; j < g->nos[i]->tamanho; j++){
if(g->nos[i]->ligacoes[j]->peso_ligacao > 3){
// potencial amigo
for(int t = 0; t < g->nos[i]->ligacoes[j]->destino->tamanho; t++){
if((g->nos[i]->ligacoes[j]->destino->ligacoes[t]->peso_ligacao > 3) && (g->nos[i]->ligacoes[j]->destino->ligacoes[t]->destino == g->nos[i])){
lista[contador] = g->nos[i]->ligacoes[j]->destino;
n[0]++;
contador++;
}
}
}
}
}
}
lista = (no_grafo**)realloc(lista,contador*sizeof(no_grafo*));
return lista;
}
no_grafo ** identifica_ciclo(grafo *g, char *nomeU, int M, int *n)
{
if(g== NULL || nomeU == NULL)
return NULL;
return NULL;
}
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include "tabdispersao.h"
#include "grafo.h"
#include "stnova.h"
/* DEFINES E VARIAVEIS GLOBAIS UTEIS PARA OS TESTES */
#define MAX_LINHA 1024
#define TAB_MSG 17
#define TAB_MSG1 997
/* VERIFICACOES IMPLEMENTADAS */
int verifica_tabela_existe(tabela_dispersao* td)
{
int er=0;
int t=tabela_existe(td, "FERNANDO");
if(t!=0)
{
printf("...verifica_tabela_existe(Remetente inexistente): tabela_existe deu diferente de 0 (ERRO)\n");
er++;
}
else
printf("...verifica_tabela_existe(Remetente inexistente): tabela_existe deu 0 (OK)\n");
t=tabela_existe(td, "ANA");
if(t!=7)
{
printf("...verifica_tabela_existe(Remetente que existe): tabela_existe deu diferente de 7 (ERRO)\n");
er++;
}
else
printf("...verifica_tabela_existe(Remetente que existe): tabela_existe deu 7 (OK)\n");
return er;
}
int verifica_tabela_listagem(tabela_dispersao* td)
{
int er=0;
mensagem** t=tabela_listagem(td, "FERNANDO");
if(t==NULL)
{
printf("...verifica_tabela_listagem(Remetente inexistente): tabela_listagem deu NULL (ERRO)\n");
er++;
} else
{
if(t[0]!=NULL)
{
printf("...verifica_tabela_listagem(Remetente inexistente): tabela_listagem a primeira posição deu diferente de NULL (ERRO)\n");
er++;
}
else
printf("...verifica_tabela_listagem(Remetente inexistente): tabela_listagem a primeira posição deu NULL (OK)\n");
}
free(t);
t=tabela_listagem(td, "ANA");
if(t==NULL)
{
printf("...verifica_tabela_listagem(Remetente inexistente): tabela_listagem deu NULL (ERRO)\n");
er++;
}
else {
int i=0;
if (t)
{
while (t[i]!=NULL)
{
i++;
}
if(i!=7)
{
printf("...verifica_tabela_listagem(Remetente que existe): tabela_listagem deu diferente de 7 mensagens(ERRO)\n");
er++;
}
else
printf("...verifica_tabela_listagem(Remetente que existe): tabela_listagem deu 7 mensagens(OK)\n");
i=0;
free(t);
}
}
return er;
}
int verifica_ligacao2(tabela_dispersao* td)
{
int er=0;
int totMsg[2]={0};
ligacao2(td,"LUIS","FERNANDO",totMsg);
if(totMsg[0]!=-1 || totMsg[1]!=-1)
{
printf("...verifica_ligacao2(Os remetentes sao inexistente): ligacao2 deu diferente de -1 -1 (ERRO)\n");
er++;
}
else
printf("...verifica_ligacao2(Os remetentes sao inexistente): ligacao2 deu -1 -1 (OK)\n");
ligacao2(td,"PEDRO","MARIA",totMsg);
if(totMsg[0]!=0 || totMsg[1]!=1)
{
printf("...verifica_ligacao2(Remetentes existentes): ligacao2 deu diferente de 0 1 (ERRO)\n");
er++;
}
else
printf("...verifica_ligacao2(Remetentes existentes): ligacao2 deu 0 1 (OK)\n");
return er;
}
int verifica_criaGrafo(tabela_dispersao* td,grafo **g)
{
int er=0;
*g=criaGrafo(td);
if (*g)
{
if((*g)->tamanho!=7)
{
printf("...verifica_criaGrafo(numero de nos): criaGrafo deu diferente de 7 (ERRO)\n");
er++;
}
else
printf("...verifica_criaGrafo(numero de nos): criaGrafo deu 7 (OK)\n");
} else
{
printf("...verifica_criaGrafo(numero de nos): criaGrafo deu NULL (ERRO)\n");
er++;
}
return er;
}
int verifica_lista_amigos(grafo *g)
{
int er=0;
int n=0;
no_grafo **nos=lista_amigos(g, "PEDRO", &n);
if(n!=0)
{
printf("...verifica_lista_amigos(sem amigos): lista_amigos deu diferente de 0(ERRO)\n");
er++;
}
else
printf("...verifica_lista_amigos(sem amigos): lista_amigos deu 0 (OK)\n");
free(nos);
nos=lista_amigos(g, "ANA", &n);
if(n==0)
{
printf("...verifica_lista_amigos(sem amigos): lista_amigos deu 0 (ERRO)\n");
er++;
}
else
if (strcmp(nos[0]->nome_user,"MAFALDA"))
{
printf("...verifica_lista_amigos(com amigos): lista_amigos deu diferente da amiga MAFALDA (ERRO)\n");
er++;
}
else
printf("...verifica_lista_amigos(com amigos): lista_amigos deu a amiga MAFALDA (OK)\n");
free(nos);
return er;
}
int verifica_identifica_ciclo(grafo *g)
{
int er=0;
no_grafo **nosciclo;
int r;
nosciclo=identifica_ciclo(g, "MARIA", 4, &r);
if(nosciclo==NULL)
{
printf("...verifica_identifica_ciclo(com ciclo): identifica_ciclo deu NULL (ERRO)\n");
er++;
}
else if(r!=4)
{
printf("...verifica_identifica_ciclo(com ciclo): identifica_ciclo deu um numero de nos diferente de 4 (ERRO)\n");
er++;
}
else
{
printf("...verifica_identifica_ciclo(com ciclo): identifica_ciclo deu um numero de nos igual a 4 (OK)\n");
printf("Os no´s foram: ");
for (int i=0;i<r-1;i++)
printf("[%d %s] : ",i+1,nosciclo[i]->nome_user);
printf("[%d %s]\n",r,nosciclo[r-1]->nome_user);
}
free(nosciclo);
return er;
}
int verifica_st_remove(estrutura *st)
{
int er=0;
elemento *el=st_remove(st,"ANA");
elemento *aux;
if(el==NULL)
{
printf("...verifica_st_remove(): st_remove deu NULL (ERRO)\n");
er++;
}
else
{ char amigo[TAMANHO_CHAVE];
int i=0;
if (strcmp(el->msg->remetente,"ANA")==0)
strcpy(amigo,el->msg->destinatario);
while (el)
{
i++;
aux=el->proximo;
if (el->msg->texto)
free(el->msg->texto);
free(el->msg);
free(el);
el=aux;
}
if((i==4) && (strcmp(amigo,"MAFALDA")==0))
{
printf("...verifica_st_remove(): st_remove removeu a amiga MAFALDA com 4 mensagens (OK)\n");
}
else
{
printf("...verifica_st_remove(): st_remove não removeu a amiga MAFALDA com 4 mensagens (ERRO)\n");
er++;
}
}
return er;
}
/*================================================= */
int verifica_tabela_existe1(tabela_dispersao* td)
{
int er=0;
int t=tabela_existe(td, "JACK");
if(t!=778)
{
printf("...verifica_tabela_existe(Remetente que existe): tabela_existe deu diferente de 778 (ERRO)\n");
er++;
}
else
printf("...verifica_tabela_existe(Remetente que existe): tabela_existe deu 778 (OK)\n");
return er;
}
int verifica_tabela_listagem1(tabela_dispersao* td)
{
int er=0;
mensagem** t=tabela_listagem(td, "JAKE");
if(t==NULL)
{
printf("...verifica_tabela_listagem(Remetente inexistente): tabela_listagem deu NULL (ERRO)\n");
er++;
}
else {
int i=0;
if (t)
{
while (t[i]!=NULL)
{
i++;
}
if(i!=521)
{
printf("...verifica_tabela_listagem(Remetente que existe): tabela_listagem deu diferente de 521 mensagens(ERRO)\n");
er++;
}
else
printf("...verifica_tabela_listagem(Remetente que existe): tabela_listagem deu 521 mensagens(OK)\n");
free(t);
}
}
return er;
}
int verifica_ligacao21(tabela_dispersao* td)
{
int er=0;
int totMsg[2]={0};
ligacao2(td,"CATES","HAMMOND",totMsg);
if(totMsg[0]!=135 || totMsg[1]!=109)
{
printf("...verifica_ligacao2(Remetentes existentes): ligacao2 deu diferente de 135 e 109 (ERRO)\n");
er++;
}
else
printf("...verifica_ligacao2(Remetentes existentes): ligacao2 deu 135 109 (OK)\n");
return er;
}
int verifica_criaGrafo1(tabela_dispersao* td,grafo **g)
{
int er=0;
*g=criaGrafo(td);
if (*g)
{
if((*g)->tamanho!=1545)
{
printf("...verifica_criaGrafo(numero de nos): criaGrafo deu diferente de 1545 nós (ERRO)\n");
er++;
}
else
printf("...verifica_criaGrafo(numero de nos): criaGrafo deu 1545 nós (OK)\n");
} else
{
printf("...verifica_criaGrafo(numero de nos): criaGrafo deu NULL (ERRO)\n");
er++;
}
return er;
}
int verifica_lista_amigos1(grafo *g)
{
int er=0;
int n=0,j,i,correto=0,resultado=0;
no_grafo **nos=lista_amigos(g, "WOMAN", &n);
char nomes[6][14]={"CHESS PLAYER","JACK","JACOB","JOE","MILES","ROB"};
if(n==0)
{
er++;
}
else
{
resultado=1;
for (i=0;i<n;i++)
{
correto=0;
for(j=0;j<6;j++)
{
if (strcmp(nos[i]->nome_user,nomes[j])==0)
{
correto=1;
break;
}
}
if (correto==0)
{
resultado=0;
}
}
if (!resultado)
{
printf("...verifica_lista_amigos(com amigos): lista_amigos deu pelos menos um diferente ""CHESS PLAYER"",""JACK"",""JACOB"",""JOE"",""MILES"",""ROB"" (ERRO)\n");
er++;
}
else
printf("...verifica_lista_amigos(com amigos): lista_amigos deu ""CHESS PLAYER"",""JACK"",""JACOB"",""JOE"",""MILES"",""ROB"" (OK)\n");
}
free(nos);
return er;
}
int verifica_identifica_ciclo1(grafo *g)
{
int er=0;
no_grafo **nosciclo;
int r;
nosciclo=identifica_ciclo(g, "ERNEST",8, &r);
if(nosciclo==NULL)
{
printf("...verifica_identifica_ciclo(com ciclo): identifica_ciclo deu NULL (ERRO)\n");
er++;
}
else if(r>=3 && r<=8)
{
printf("...verifica_identifica_ciclo(com ciclo): identifica_ciclo deu um numero de nos está entre 3 e 8 (OK)\n");
printf("Os no´s foram: ");
for (int i=0;i<r-1;i++)
printf("[%d %s] : ",i+1,nosciclo[i]->nome_user);
printf("[%d %s]\n",r,nosciclo[r-1]->nome_user);
}
else
{
printf("...verifica_identifica_ciclo(com ciclo): identifica_ciclo deu um numero de nos que não está entre 3 e 8 (ERRO)\n");
printf("Os no´s foram: ");
for (int i=0;i<r-1;i++)
printf("[%d %s] : ",i+1,nosciclo[i]->nome_user);
printf("[%d %s]\n",r,nosciclo[r-1]->nome_user);
er++;
}
free(nosciclo);
return er;
}
int verifica_st_remove1(estrutura *st)
{
int er=0;
clock_t start_t, end_t;
start_t = clock();
elemento *el=st_remove(st,"HELEN");
end_t = clock();
elemento *aux;
if(el==NULL)
{
printf("...verifica_st_remove(): st_remove deu NULL (ERRO)\n");
er++;
}
else
{ char amigo[TAMANHO_CHAVE];
int i=0;
if (strcmp(el->msg->remetente,"HELEN")==0)
strcpy(amigo,el->msg->destinatario);
while (el)
{
i++;
aux=el->proximo;
if (el->msg->texto)
free(el->msg->texto);
free(el->msg);
free(el);
el=aux;
}
if((i==67) && (strcmp(amigo,"CALVIN")==0))
{
printf("...verifica_st_remove(): st_remove removeu a amiga CALVIN com 67 mensagens (OK)\n");
printf("\tTempo a remover: %.8f\n", (double)(end_t - start_t) / CLOCKS_PER_SEC);
}
else
{
printf("...verifica_st_remove(): st_remove removeu a amiga %s com %d mensagens devia ser (CALVIN,67) (ERRO)\n",amigo,i);
er++;
}
}
return er;
}
/*================================================= */
int main()
{
int errCount=0, err;
char *fi= "dados.txt";
tabela_dispersao* td;
grafo *g;
td=tabela_carrega(fi,TAB_MSG);
printf("INICIO DOS TESTES: Boa sorte\n\n");
printf("Teste com poucos utilizadores\n\n");
err = verifica_tabela_existe( td);
if(err)
{
printf("ERRO: %d erros encontrados em verifica_tabela_existe\n\n", err);
errCount += err;
}
else
{
printf("OK: verifica_tabela_existe passou\n\n");
}
err = verifica_tabela_listagem( td);
if(err)
{
printf("ERRO: %d erros encontrados em verifica_tabela_listagem\n\n", err);
errCount += err;
}
else
{
printf("OK: verifica_tabela_listagem passou\n\n");
}
err = verifica_ligacao2( td);
if(err)
{
printf("ERRO: %d erros encontrados em verifica_ligacao2\n\n", err);
errCount += err;
}
else
{
printf("OK: verifica_ligacao2 passou\n\n");
}
err = verifica_criaGrafo(td,&g);
if(err)
{
printf("ERRO: %d erros encontrados em verifica_criaGrafo\n\n", err);
errCount += err;
}
else
{
printf("OK: verifica_criaGrafo passou\n\n");
}
err = verifica_lista_amigos(g);
if(err)
{
printf("ERRO: %d erros encontrados em verifica_lista_amigos\n\n", err);
errCount += err;
}
else
{
printf("OK: verifica_lista_amigos passou\n\n");
}
err = verifica_identifica_ciclo(g);
if(err)
{
printf("ERRO: %d erros encontrados em verifica_identifica_ciclo\n\n", err);
errCount += err;
}
else
{
printf("OK: verifica_identifica_ciclo passou\n\n");
}
estrutura *st=st_nova();
st_importa_tabela(st,td);
err = verifica_st_remove(st);
if(err)
{
printf("ERRO: %d erros encontrados em verifica_st_remove\n\n", err);
errCount += err;
}
else
{
printf("OK: verifica_st_remove passou\n\n");
}
st_apaga(st);
tabela_apaga(td);
grafo_apaga(g);
/*================================================= */
/* Com um ficheiro maior */
char *fic= "dataset_partA.txt";
printf("Teste com muitos utilizadores\n\n");
td=tabela_carrega(fic,TAB_MSG1);
err = verifica_tabela_existe1(td);
if(err)
{
printf("ERRO: %d erros encontrados em verifica_st_remove\n\n", err);
errCount += err;
}
else
{
printf("OK: verifica_st_remove passou\n\n");
}
err = verifica_tabela_listagem1( td);
if(err)
{
printf("ERRO: %d erros encontrados em verifica_tabela_listagem\n\n", err);
errCount += err;
}
else
{
printf("OK: verifica_tabela_listagem passou\n\n");
}
err = verifica_ligacao21( td);
if(err)
{
printf("ERRO: %d erros encontrados em verifica_ligacao2\n\n", err);
errCount += err;
}
else
{
printf("OK: verifica_ligacao2 passou\n\n");
}
err = verifica_criaGrafo1(td,&g);
if(err)
{
printf("ERRO: %d erros encontrados em verifica_criaGrafo\n\n", err);
errCount += err;
}
else
{
printf("OK: verifica_criaGrafo passou\n\n");
}
err = verifica_lista_amigos1(g);
if(err)
{
printf("ERRO: %d erros encontrados em verifica_lista_amigos\n\n", err);
errCount += err;
}
else
{
printf("OK: verifica_lista_amigos passou\n\n");
}
err = verifica_identifica_ciclo1(g);
if(err)
{
printf("ERRO: %d erros encontrados em verifica_identifica_ciclo\n\n", err);
errCount += err;
}
else
{
printf("OK: verifica_identifica_ciclo passou\n\n");
}
st=st_nova();
st_importa_tabela(st,td);
err = verifica_st_remove1(st);
if(err)
{
printf("ERRO: %d erros encontrados em verifica_st_remove\n\n", err);
errCount += err;
}
else
{
printf("OK: verifica_st_remove passou\n\n");
}
st_apaga(st);
tabela_apaga(td);
grafo_apaga(g);
if (errCount == 0)
printf("FIM DOS TESTES: Todos os testes passaram\n");
else
printf("FIM DOS TESTES: Foram encontrados %d ERROS no total\n", errCount);
return 0;
}
regarding:
g->nos = (no_grafo **)malloc(sizeof(no_grafo*))`
the returned type is void* which can be assigned to any pointer. Casting just clutters the code and is error prone. Suggest removing the cast.
since no_grafo is a typedefstruct and you want to allocate enough memory for the struct, then remove the * from the parameter: sizeof(no_grafo*) should be: sizeof( no_grafo )
Always check (!=NULL) the returned value to assure the operation was successful. If not successful (==NULL) then call:
perror( "malloc failed" );
which will output to stderr both the error message "malloc failed" and the text reason the system thinks the error occurred.
Related
Error "a label can only be part of a statement" when compiling file line 17 in the main() function [duplicate]
This question already has answers here: Why can we not declare a variable after a switch case colon without using curly braces? (3 answers) Closed last month. I have a problem compiling the code in the main file at line 17. The error is "a label can only be part of a statement and a declaration is not a statement". #ifndef HEADER_H_INCLUDED #define HEADER_H_INCLUDED #define TAILLE_MAX_NOM 50 // Définition du type Compte typedef struct { int RIB; float solde; char etat[TAILLE_MAX_NOM]; float plafond_credit; int nb_operations; float operations[100]; } Compte; Compte T_Compte[100]; int menu(); void CreerCompte(Compte *C); int ChercherCompte(Compte T_Compte[],int NC,int RIB ); void AjouterCompte (Compte T_Compte[], int *NC, Compte C); float Ajouter_Retirer (Compte T_Compte[], int NC, float M,int RIB); void ListeComptes(Compte T_Compte[], int NC); void StatCompte (Compte T_Compte[], int NC, int *PNBA,int *PNBR ,int RIB); void Prime (Compte T_Compte[], int NC); #endif // HEADER_H_INCLUDED #include <stdio.h> #include <stdlib.h> #include <string.h> #include "header.h" int menu() { int choix; printf("\n\n -> Menu <- \n\n"); printf(" 1 - Ajouter un Nouveau Compte \n"); printf(" 2 - Afficher les comptes de la banque \n"); printf(" 3 - Ajouter une operation a un compte\n"); printf(" 4 - Attribuer une prime aux meilleurs comptes bancaires \n"); printf(" 0 - Quitte\n"); printf("\n --------------------------------------\n"); do { printf(" -> Tapez votre choix : "); scanf("%d",&choix); printf("\n\n"); } while (choix>4 || choix<0); return choix; } void CreerCompte(Compte *C) { printf("RIB du compte : "); scanf("%d", &C->RIB); printf("Solde initial du compte (supérieur ou égal à 50) : "); scanf("%f", &C->solde); while (C->solde < 50) { printf("Le solde initial doit être supérieur ou égal à 50 !\n"); printf("Solde initial du compte (supérieur ou égal à 50) : "); scanf("%f", &C->solde); } strcpy(C->etat, "debiteur"); printf("Plafond de crédit du compte (strictement négatif supérieur à -500) : "); scanf("%f", &C->plafond_credit); while (C->plafond_credit >= 0 || C->plafond_credit <= -500) { printf("Le plafond de crédit doit être un montant strictement négatif supérieur à -500 !\n"); printf("Plafond de crédit du compte (strictement négatif supérieur à -500) : "); scanf("%f", &C->plafond_credit); } C->nb_operations = 0; } int ChercherCompte(Compte T_Compte[], int NC, int RIB) { for (int i = 0; i < NC; i++) { if (T_Compte[i].RIB == RIB) { return i; } } return -1; } void AjouterCompte(Compte T_Compte[], int *NC, Compte C) { if (ChercherCompte(T_Compte, *NC, C.RIB) != -1) { printf("Un compte avec ce RIB existe déjà !\n"); return; } T_Compte[*NC] = C; (*NC)++; } float Ajouter_Retirer(Compte T_Compte[], int NC, float M, int RIB) { // Vérifie que la somme à ajouter ou retirer est non nulle if (M == 0) { printf("La somme à ajouter ou retirer ne peut pas être nulle !\n"); return -1; } // Cherche le compte dans le tableau int pos = ChercherCompte(T_Compte, NC, RIB); // Vérifie que le compte existe if (pos == -1) { printf("Le compte avec le RIB spécifié n'existe pas !\n"); return -1; } Compte C = T_Compte[pos]; // Vérifie que l'opération de retrait peut être effectuée if (M < 0 && (C.solde + M < -C.plafond_credit)) { printf("Opération de retrait impossible !\n"); return -1; } // Effectue l'opération C.solde += M; C.nb_operations++; T_Compte[pos] = C; return C.solde; } void ListeComptes(Compte T_Compte[], int NC) { printf("Liste des comptes de la banque :\n"); for (int i = 0; i < NC; i++) { Compte C = T_Compte[i]; printf("RIB : %d, Solde : %.2f, Etat : %s, Plafond de crédit : %.2f, Nombre d'opérations : %d\n", C.RIB, C.solde, C.etat, C.plafond_credit, C.nb_operations); } }void StatCompte(Compte T_Compte[], int NC, int *PNBA, int *PNBR, int RIB) { // Initialise les compteurs à 0 *PNBA = 0; *PNBR = 0; // Cherche le compte dans le tableau int pos = ChercherCompte(T_Compte, NC, RIB); if (pos == -1) { printf("Le compte avec ce RIB n'existe pas !\n"); return; } // Parcours les opérations du compte Compte C = T_Compte[pos]; for (int i = 0; i < C.nb_operations; i++) { if (C.operations[i] > 0) { (*PNBA)++; } else if (C.operations[i] < 0) { (*PNBR)++; } } } void Prime(Compte T_Compte[], int NC) { printf("Attribution de la prime aux meilleurs comptes de la banque :\n"); for (int i = 0; i < NC; i++) { Compte C = T_Compte[i]; // Vérifie que le compte est débiteur if (strcmp(C.etat, "debiteur") == 0) { int nb_ajout = 0; int nb_retrait = 0; // Parcours les opérations du compte pour compter le nombre d'opérations d'ajout et de retrait for (int j = 0; j < C.nb_operations; j++) { if (C.operations[j] > 0) { nb_ajout++; } else if (C.operations[j] < 0) { nb_retrait++; } } // Vérifie que le nombre d'opérations d'ajout est supérieur aux nombres d'opérations de retrait if (nb_ajout > nb_retrait) { float prime = (C.solde / C.nb_operations) * 0.5; printf("RIB : %d - Prime : %.2f\n", C.RIB, prime); } } } } //source file/ #include <stdio.h> #include <stdlib.h> #include <string.h> #include "header.h" int main() { // Initialize the array of accounts int NC = 0; // Display the menu and get the user's choice int choix = menu(); while (choix != 0) { switch (choix) { case 1: Compte C; getchar(); CreerCompte(&C); AjouterCompte(T_Compte, &NC, C); break; case 2: // Display the accounts ListeComptes(T_Compte, NC); break; case 3: // Add or remove money from an account printf("RIB du compte : "); int RIB; scanf("%d", &RIB); printf("Somme à ajouter ou retirer : "); float M; scanf("%f", &M); float solde = Ajouter_Retirer(T_Compte, NC, M, RIB); if (solde != -1) { printf("Nouveau solde : %.2f\n", solde); } break; case 4: // Attribute a prize to the best accounts Prime(T_Compte, NC); break; } // Display the menu and get the user's choice again choix = menu(); } printf("Au revoir !\n"); return 0; } Here is the main function that uses 4 switches to perform the following functions: Add a new account Display the accounts of the bank Add an operation to an account Attribute a prize to the best accounts
Is this line 17? Compte C; If so, you need to scope the variable C. Change the case 1: handler to this: case 1: { Compte C; getchar(); CreerCompte(&C); AjouterCompte(T_Compte, &NC, C); break; }
Why do I get a segfault when the for loop finishes adding elements to a list?
My code is an algorithm to solve a problem related to the longest-job first. It receives the number of process (num_programas) and for each process it gets an time (instante) and a weight(carga). When i'm inserting on the list it inserts all process but in the last one it gets segmentation fault. It is sorting normally (i've printed the header each time the loops executes), it just gets segmentation fault in the last execution of the for loop (for instance: num programas = 7, stops working when i = 6) /* Vou fazer com lista duplamente encadeada só pra facilitar na funcao proximo. Não vou otimizar porque preciso me livrar logo pra fazer o projeto e estudar puta merda que codigo horrivel, espero que o aleardo nao leia. Otimizar depois. 8 74 11 7 20 53 17 78 13 52 11 63 19 89 17 15 20 */ #include <stdio.h> #include <stdlib.h> struct processo { int temp; int carga; struct processo *next; struct processo *prev; }; struct processo *cadastrarProcesso(struct processo *header, int instante, int carga); struct processo *executarAtividade(struct processo *header, int *tempo_executando); struct processo *inserirProcessos(struct processo *programa, struct processo *header); void imprimirLista(struct processo *header); struct processo *proximo(struct processo *header, int *tempo_executando); int main() { struct processo *header, *aux; header = NULL; int num_programas, instante, carga, i, tempo_executando = 0; scanf("%d", &num_programas); for (i = 0; i < num_programas; i++) { scanf("%d %d", &instante, &carga); header = cadastrarProcesso(header, instante, carga); } /* Cadastrou e ordenou em ordem de tempo, aí tem que criar uma funcao para ir printando */ imprimirLista(header); for (i = 0; i < num_programas; i++) { header = executarAtividade(header, &tempo_executando); } return 0; } struct processo *cadastrarProcesso(struct processo *header, int instante, int carga) { struct processo *aux; aux = malloc(sizeof(struct processo)); aux->next = NULL; aux->prev = NULL; aux->carga = carga; aux->temp = instante; header = inserirProcessos(aux, header); return header; } struct processo *inserirProcessos(struct processo *programa, struct processo *header) { struct processo *aux; if (header == NULL) { header = programa; return header; } aux = header; while (aux->next != NULL && programa->temp > aux->temp) { aux = aux->next; } if (aux == header) { // tem que fazer essa verificacao pq ele sai do while tanto se o while->next for nulo e tambem se for maior if (programa->temp < aux->temp) { // insere depois do header, se tornando o novo header aux->prev = programa; programa->next = aux; return programa; // é o novo header, retorna ele } else // insere depois) { programa->next = aux->next; aux->next = programa; programa->prev = aux; return header; } } else { // vamos ver se ele saiu porque while->next é nulo ou porque é maior if (programa->temp < aux->temp) { (aux->prev)->next = programa; programa->prev = aux->prev; programa->next = aux; aux->prev = programa; return header; } else // maior igual { programa->next = aux->next; programa->prev = aux; aux->next = programa; return header; } } } void imprimirLista(struct processo *header) // funcao auxiliar { struct processo *aux; aux = header; while (aux != NULL) { printf("%d ", aux->temp); aux = aux->next; } } struct processo *executarAtividade(struct processo *header, int *tempo_executando) { // lembrando que já está dentro de um for struct processo *aux; if (*tempo_executando == 0) { aux = header; *tempo_executando = aux->temp + aux->carga; header = aux->next; printf("%d ", aux->carga); // imprime a carga da saida que foi executada (aux->next)->prev = NULL; aux->next = NULL; free(aux); return header; } else { // TODO: reduzir esse codigo zendo tudo dentro do mesmo IF, só olhando a condicao do proximo aux = proximo(header, tempo_executando); // recebe o que vai ser executado *tempo_executando = *tempo_executando + aux->carga; if (aux == header) // se o aux { header = aux->next; printf("%d ", aux->carga); (aux->next)->prev = NULL; aux->next = NULL; free(aux); return header; } else { if (aux->next != NULL) { (aux->next)->prev = aux->prev; (aux->prev)->next = aux->next; } else { (aux->prev)->next = aux->next; } printf("%d ", aux->carga); free(aux); return header; } } } struct processo *proximo(struct processo *header, int *tempo_executando) { struct processo *aux, *escolhido; int maior_carga; aux = header; maior_carga = aux->carga; escolhido = aux; if (aux->temp >= *tempo_executando) { //*tempo_executando = *tempo_executando + (aux->temp - *tempo_executando); return aux; } else { while (aux->next != NULL && aux->temp < *tempo_executando) { aux = aux->next; if (aux->carga > maior_carga) { maior_carga = aux->carga; escolhido = aux; } else if (aux->carga == maior_carga) { // o critério de desempate é o menor tempo if (aux->carga < escolhido->carga) { escolhido = aux; } } } return escolhido; } }
In this code: if (aux == header) // se o aux { header = aux->next; printf("%d ", aux->carga); (aux->next)->prev = NULL; // crash here with aux->next == NULL aux->next = NULL; free(aux); return header; } when you are removing the last element (aux == header), aux->next is NULL and attempting to dereference it causes a crash. You must check that aux->next != NULL before doing that. P.S. The aux->next = NULL is useless if you immediately call free(aux).
Segmentation fault when commenting 2 free (Sokoban game)
I've been trying to solve a segmentation fault since yesterday, it's driving me crazy... So I've got this program that I use to implement the sokoban game, in which a map is given, and a plan like "NSEW" is given, meaning that I want the player to move north, then south, then etc... on the map given. map* replay(map* map_loaded, int length, char* plan){ map* new_map=move(map_loaded,plan[0]); map* old_map=deep_copy(new_map); for (int i=1 ; i<length ; i++){ free(new_map->p_char); free(new_map); new_map=move(old_map,plan[i]); free(old_map->p_char); free(old_map); old_map=deep_copy(new_map); } free(old_map->p_char); free(old_map); return new_map; } Map is a structure defined as following : typedef struct map map; struct map{ int width; int height; char* p_char; }; The move function does one movement ; The deep_copy makes a deep copy of a map struct : map* deep_copy(map* map_loaded){ map* new_map=malloc(sizeof(map)); char* p_array=map_loaded->p_char; int width=map_loaded->width; int height=map_loaded->height; new_map->width=width; new_map->height=height; char* p_new=malloc(sizeof(char)*width*height); for (int i=0 ; i<width*height ; i++){ p_new[i]=p_array[i]; } new_map->p_char=p_new; return(new_map); } And what happens is that if I leave the code like that, if the length chosen ( the number of movements I want the player to do) is too high (depends on the map and the movements), when executing a replay.c program : int main(int argc, char *argv[]){ if (argc != 4) { fprintf(stderr, "You must provide a file name or enough elements!\n"); exit(EXIT_FAILURE); } map* map_loaded=load(argv[1]); int length=atoi(argv[2]); char* plan=argv[3]; map* new_map=replay(map_loaded,length,plan); print_map(new_map); free(new_map->p_char); free(new_map); free(map_loaded->p_char); free(map_loaded); return 1; } I get a segmentation fault... But if I do : //free(old_map->p_char); //free(old_map); Everything works perfect !! I really don't understand why... The problem is if I do those free valgrind tells me I don't have as many free as allocs, which is normal... I would really appreciate any help given... Thanks in advance if you've been brave enough to read me until this point ! Edit : Here is my move function ; map* move(map* map_loaded, char dir){ int pos=Position(map_loaded); int width=map_loaded->width; map* new_map=deep_copy(map_loaded); char* p_new_array=new_map->p_char; switch(dir){ case 'N': if (p_new_array[pos-width]=='#'){ // Si il y a un mur au dessus return(map_loaded); } if ((p_new_array[pos-width]=='$' && p_new_array[pos-2*width]=='$') ||(p_new_array[pos-width]=='$' && p_new_array[pos-2*width]=='*') ||(p_new_array[pos-width]=='*' && p_new_array[pos-2*width]=='$') ||(p_new_array[pos-width]=='*' && p_new_array[pos-2*width]=='*')){ //s'il y a 2 caisses au dessus return(map_loaded); } if ((p_new_array[pos-width]=='$' && p_new_array[pos-2*width]=='#') //s'il y a une caisse au niveau -1 et un mur au niveau -2 ||(p_new_array[pos-width]=='*' && p_new_array[pos-2*width]=='#')){ return(map_loaded); } // On vérifie d'abord s'il y a une caisse à déplacer if (p_new_array[pos-width]=='$' || p_new_array[pos-width]=='*'){ if (p_new_array[pos-2*width]=='.'){ p_new_array[pos-2*width]='*'; } else { p_new_array[pos-2*width]='$'; } if (p_new_array[pos-width]=='*'){ p_new_array[pos-width]='.'; } else{ p_new_array[pos-width]=' '; } } //On change le char en position du joueur if (p_new_array[pos]=='+'){ p_new_array[pos-width]='#'; p_new_array[pos]='.'; } else if (p_new_array[pos-width]=='.'){ p_new_array[pos-width]='+'; p_new_array[pos]=' '; } else { p_new_array[pos-width]='#'; p_new_array[pos]=' '; } break; case 'S': if (p_new_array[pos+width]=='#'){ // Si il y a un mur en dessous return(map_loaded); } if ((p_new_array[pos+width]=='$' && p_new_array[pos+2*width]=='$') ||(p_new_array[pos+width]=='$' && p_new_array[pos+2*width]=='*') ||(p_new_array[pos+width]=='*' && p_new_array[pos+2*width]=='$') ||(p_new_array[pos+width]=='*' && p_new_array[pos+2*width]=='*')){//s'il y a 2 caisses au dessus return(map_loaded); } if ((p_new_array[pos+width]=='$' && p_new_array[pos+2*width]=='#') //s'il y a une caisse au niveau +1 et un mur au niveau +2 ||(p_new_array[pos+width]=='*' && p_new_array[pos+2*width]=='#')){ return(map_loaded); } // On vérifie d'abord s'il y a une caisse à déplacer if (p_new_array[pos+width]=='$' || p_new_array[pos+width]=='*'){ if (p_new_array[pos+2*width]=='.'){ p_new_array[pos+2*width]='*'; } else { p_new_array[pos+2*width]='$'; } if (p_new_array[pos+width]=='*'){ p_new_array[pos+width]='.'; } else{ p_new_array[pos+width]=' '; } } //On change le char en position du joueur if (p_new_array[pos]=='+'){ p_new_array[pos+width]='#'; p_new_array[pos]='.'; } else if (p_new_array[pos+width]=='.'){ p_new_array[pos+width]='+'; p_new_array[pos]=' '; } else { p_new_array[pos+width]='#'; p_new_array[pos]=' '; } break; case 'W': if (p_new_array[pos-1]=='#'){ // Si il y a un mur en dessous return(map_loaded); } if ((p_new_array[pos-1]=='$' && p_new_array[pos-2]=='$') ||(p_new_array[pos-1]=='$' && p_new_array[pos-2]=='*') ||(p_new_array[pos-1]=='*' && p_new_array[pos-2]=='$') ||(p_new_array[pos-1]=='*' && p_new_array[pos-2]=='*')){ //s'il y a 2 caisses à gauche return(map_loaded); } if ((p_new_array[pos-1]=='$' && p_new_array[pos-2]=='#') //s'il y a une caisse au niveau -1 et un mur au niveau -2 ||(p_new_array[pos-1]=='*' && p_new_array[pos-2]=='#')){ return(map_loaded); } // On vérifie d'abord s'il y a une caisse à déplacer if (p_new_array[pos-1]=='$' || p_new_array[pos-1]=='*'){ if (p_new_array[pos-2]=='.'){ p_new_array[pos-2]='*'; } else { p_new_array[pos-2]='$'; } if (p_new_array[pos-1]=='*'){ p_new_array[pos-1]='.'; } else{ p_new_array[pos-1]=' '; } } //On change le char en position du joueur if (p_new_array[pos]=='+'){ p_new_array[pos-1]='#'; p_new_array[pos]='.'; } else if (p_new_array[pos-1]=='.'){ p_new_array[pos-1]='+'; p_new_array[pos]=' '; } else { p_new_array[pos-1]='#'; p_new_array[pos]=' '; } break; case 'E': if (p_new_array[pos+1]=='#') {// Si il y a un mur à droite return(map_loaded); } if ((p_new_array[pos+1]=='$' && p_new_array[pos+2]=='$') ||(p_new_array[pos+1]=='$' && p_new_array[pos+2]=='*') ||(p_new_array[pos+1]=='*' && p_new_array[pos+2]=='$') ||(p_new_array[pos+1]=='*' && p_new_array[pos+2]=='*')){ //s'il y a 2 caisses à droite return(map_loaded); } if ((p_new_array[pos+1]=='$' && p_new_array[pos+2]=='#') //s'il y a une caisse au niveau +1 et un mur au niveau +2 ||(p_new_array[pos+1]=='*' && p_new_array[pos+2]=='#')){ return(map_loaded); } // On vérifie d'abord s'il y a une caisse à déplacer if (p_new_array[pos+1]=='$' || p_new_array[pos+1]=='*'){ if (p_new_array[pos+2]=='.'){ p_new_array[pos+2]='*'; } else { p_new_array[pos+2]='$'; } if (p_new_array[pos+1]=='*'){ p_new_array[pos+1]='.'; } else{ p_new_array[pos+1]=' '; } } //On change le char en position du joueur if (p_new_array[pos]=='+'){ p_new_array[pos+1]='#'; p_new_array[pos]='.'; } else if (p_new_array[pos+1]=='.'){ p_new_array[pos+1]='+'; p_new_array[pos]=' '; } else { p_new_array[pos+1]='#'; p_new_array[pos]=' '; } break; } return(new_map); } And here is the load function ; char* Array_Creator(char* filename){ FILE* p_file = fopen(filename, "r"); char* p_array = NULL; if (p_file == NULL) { exit(EXIT_FAILURE); } else{ size_t size=1; int c; while (getc(p_file)!=EOF) { size++; } fseek(p_file,0,SEEK_SET); while ((c=getc(p_file))!='\n' && c!=EOF) { //on se débarasse de la première ligne size--; } p_array=(char*)malloc(sizeof(char)*size); if (p_array!=NULL) { //si jamais le malloc ne fonctionne pas for(size_t i=0; i<size-1; i++) { p_array[i]=(char)getc(p_file); if (p_array[i] == '\n') { // si le caractère est une nouvelle ligne, on s'en sépare i--; // on ajuste alors la taille et l'indice size--; } } p_array[size-1]='\0'; } fclose(p_file); } return p_array; } //La fonction Dimensions permet de récupérer les dimensions d'une map couple Dimensions(char *p_char){ FILE *p_file = NULL; p_file=fopen(p_char, "r"); if (p_file == NULL) { fprintf(stderr, "Cannot read file %s!\n", p_char); exit(EXIT_FAILURE); } couple dim={0,0}; //la structure couple est déf dans le loader.h int width = 0; int height = 0; int fscanf_result = 0; fscanf_result = fscanf(p_file, "%d %d\n", &width, &height); if (fscanf_result != 2) { fprintf(stderr, "First line is not syntactically correct!\n"); exit(EXIT_FAILURE); } dim.x=width; dim.y=height; fclose(p_file); return dim; } //La fonction Load est celle demandée et permettant de charger une carte ; elle utilise Dimensions et Array_Creator map* load(char *filename){ map* map_loaded=malloc(sizeof(map)); //on alloue dynamiquement la map //Dans un premier temps on récupère les dimensions couple map_dim={0,0}; map_dim=Dimensions(filename); map_loaded->width=map_dim.x; map_loaded->height=map_dim.y; //Dans un second temps on définit le tableau 1D contenant l'ensemble des éléments de la map char* p_char=Array_Creator(filename); map_loaded->p_char=p_char; return map_loaded; } The command line is, for example : ./replay ./data/soko.in 4 7"NSWSESNWW"
In the move function, should change all return(map_loaded); => return(new_map); It will map_loaded to be freed twice when the move function returns map_loaded Code analysis map *replay(map *map_loaded, int length, char *plan) { map *new_map = move(map_loaded, plan[0]); // [2] set new_map to map_loaded map *old_map = deep_copy(new_map); for (int i = 1 ; i < length ; i++) { free(new_map->p_char); free(new_map); // [3] new_map be freed, // equivalent map_loaded be freed new_map = move(old_map, plan[i]); ... } ... return new_map; } int main(int argc, char *argv[]) ... map *map_loaded = load(argv[1]); // [1] map_loaded be malloc ... map *new_map = replay(map_loaded, length, plan); ... free(map_loaded->p_char); free(map_loaded); // [4] map_loaded be freed ... }
Writing my own shell for redirecting and pipes in C
I have been trying to write a shell in C but i keep getting e segmentation fault when running ls > test.txt (before implementing pipes it worked just fine) . Here is the code. sorry if it is too long and not formated properly. #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <sys/wait.h> #include <fcntl.h> #define MAX 1024 /* fonction separe donne en exercise*/ char **separe(char *chaine, const char *separateurs) { char **tab; int i, s, m, size = 10; tab = malloc(size * sizeof(char*)); m = 0; i = 0; while (chaine[i] != 0) { // saute un séparateur for (s = 0; separateurs[s] != 0; s++) if (chaine[i] == separateurs[s]) break; if (separateurs[s] != 0) { chaine[i++] = 0; // met un fin de chaine à la place du séparateur et avance continue; // les séparateurs n'ont pas été épuisés } if (chaine[i] != 0) tab[m++] = chaine + i; if (m == size) { // si j'atteinds la limite de la taille de mon tableau, je l'agrandis. size += 10; tab = realloc(tab, size * sizeof(char*)); } // saute les caractères non séparateurs for (; chaine[i] != 0; i++) { for (s = 0; separateurs[s] != 0; s++) if (chaine[i] == separateurs[s]) break; if (separateurs[s] != 0) break; // trouvé un caractère séparateur, j'arrête d'avancer et je passe au mot suivant } } tab[m] = NULL; return(tab); } void decaler2gauche(char ** tab, int pos) { int i = pos; while( tab[i+2] != NULL ) { tab[i] = tab[i+2]; i++; } tab[i] = NULL; } char** pipetest( char **arg) { int sizeTab = 0; int k,j; char **newtab; for (k = 0; arg[k] != NULL; k++) { sizeTab++; } int i =0; while( arg[i] != NULL ) { if( strncmp(arg[i],"|",1) == 0 ) { for (j=0;j < i ; j++){ newtab[i] = arg[i]; } break; } i++; } newtab[i] = NULL; return newtab; } char** pipetest2( char **arg) { int sizeTab = 0; int k , j; char **newtab; for (k = 0; arg[k] != NULL; k++) { sizeTab++; } int i =0; while( arg[i] != NULL ) { if( strncmp(arg[i],"|",1) == 0 ) { for ( j= i+1 ; j < sizeTab ; j++ ) { newtab[j] = arg[j]; } break; } i++; } newtab[sizeTab] = NULL; return newtab; } /* la fonction main*/ int main(int argc, char *argv[]) { char cmd[MAX]; char **commande; //ici on met la commande char *newcommande[MAX]; // ici on met la commande apres avoir verifie le contenu de commande int i, j, k,t,a, fd, fd2, raison ; // les variables utilise char *tmp, *new_path , *new_path1 , *new_path2; char *ge_path, *path, **tab; int test; int status , status2; // la variable test pour le access char **commande1; char **commande2; pid_t pid , pid2; // récupère la valeur de $PATH ge_path = getenv("PATH"); // crée une copie locale modifiable // (on ne doit pas modifier la zone mémoire renvoyée par getenv) path = malloc(strlen(ge_path) + 1); strcpy(path, ge_path); tab = separe(path, ":"); while (1) { int copy = 0; int paste = 0; int piping = 0; int fdout; int fdin; int tabfd[2]; printf("myshell > "); fgets(cmd, MAX, stdin); commande = separe(cmd, " \n"); /* Cette boucle verifie si la commande passe en parametre est dans le PAth ou pas*/ for (i = 0; tab[i] != NULL; i++) { char tmp[MAX]; sprintf(tmp, "%s/%s", tab[i], commande[0]); if ((test = access(tmp, X_OK)) == 0) { new_path = tmp; break; } } char* fileNameIn; char* fileNameOut; for (j = 0; commande[j] != NULL; j++) { if (strcmp(commande[j], ">") == 0) //out { fileNameOut = commande[j + 1]; fdout = open(fileNameOut, O_CREAT | O_WRONLY | O_TRUNC, 0666); if (fdout == -1) { perror("open\n"); exit(1); } decaler2gauche(commande,j); copy = 1; } if (strcmp(commande[j], "<") == 0) //in { fileNameIn = commande[j + 1]; printf("%s\n", fileNameIn); fdin = open(fileNameIn, O_RDONLY); if (fdin == -1) { perror("open\n"); exit(1); } paste = 1; decaler2gauche(commande,j); } if (strcmp(commande[j], "|") == 0) // pipe { { piping = 1; } newcommande[j] = commande[j]; } if (piping) { commande1=pipetest(newcommande); commande2=pipetest2(newcommande); for (i = 0; tab[i] != NULL; i++) { char tmp[MAX]; sprintf(tmp, "%s/%s", tab[i], commande1[0]); if ((test = access(tmp, X_OK)) == 0) { new_path1 = tmp; break; } } for (i = 0; tab[i] != NULL; i++) { char tmp[MAX]; sprintf(tmp, "%s/%s", tab[i], commande2[0]); if ((test = access(tmp, X_OK)) == 0) { new_path2 = tmp; break; } } pipe(tabfd); switch (pid=fork()) { case -1: // le cas d erreur perror("fork"); exit(1); case 0:// le fils close(1); dup(tabfd[1]); if (paste) { if (dup2(fdin, 0) == -1) { perror("dup2 fdin \n"); exit(1); } } if (copy) { if (dup2(fdout, 1) == -1) { perror("dup2 fdin \n"); exit(1); } } execv(new_path1, commande1); perror("cmd"); exit(1); default : wait(&status2); break; } switch (pid2=fork()) { case -1: // le cas d erreur perror("fork"); exit(1); case 0:// le fils close(0); dup(tabfd[0]); if (paste) { if (dup2(fdin, 0) == -1) { perror("dup2 fdin \n"); exit(1); } } if (copy) { if (dup2(fdout, 1) == -1) { perror("dup2 fdin \n"); exit(1); } } execv(new_path2, commande2); perror("cmd"); exit(1); default : wait(&status); break; } close(tabfd[0]); close(tabfd[1]); } else { switch (pid = fork()) { case -1: // le cas d erreur perror("fork"); exit(1); case 0:// le fils if (paste) { if (dup2(fdin, STDIN_FILENO) == -1) { perror("dup2 fdin \n"); exit(1); }; } if (copy) { if (dup2(fdout, STDOUT_FILENO) == -1) { perror("dup2 fdin \n"); exit(1); }; } execv(new_path, commande); perror("cmd"); exit(1); default: wait(&status); break ; } } free(commande); free(tmp); } free(tab); //free(commande); free(path); free(new_path); exit(0); }
Assignment from incompatible pointer type in Eclipse
I have seen many questions on this topic, but couldn't take much sense from them and couldn't compare it to my code. I'm not sure what I'm doing wrong, but it appears as a warning on Eclipse, and I think it might be what's making my function behave differently than it should. The comments and variables are in portuguese, so if you need me to translate any part of it, or to tell you what each function should do, just tell me. #include <stdio.h> #include <stdlib.h> #include <string.h> #include "grafo.h" typedef struct _relemento { /** string armazenada */ char *nome; int x, y, id; struct _elemento *proximo; } robot_lista; typedef struct { robot_lista *raiz; int tamanho; } listarobots; typedef struct _elemento { /** string armazenada */ int x; int y; int v; struct _elemento *proximo; } elemento_lista; typedef struct { elemento_lista *raiz; int tamanho; } lista; listarobots* listarobots_nova() { /* cria lista */ listarobots *lst = (listarobots*) malloc(sizeof(listarobots)); if(lst == NULL) return NULL; /* lista esta' vazia */ lst->raiz = NULL; lst->tamanho = 0; return lst; } robot_lista* novorobot_str(const char* valor, int x, int y, int id) { /* aloca memoria para a estrutura lista */ robot_lista *item = (robot_lista *) malloc(sizeof(robot_lista)); if(item == NULL) return NULL; /* aloca memoria para string */ item->nome = (char *) malloc((strlen(valor)+1)*sizeof(char)); if(item->nome == NULL) { free(item); return NULL; } /* copia valor */ strcpy(item->nome, valor); item->x=x; item->y=y; item->id=id; /* item ainda nao tem proximo */ item->proximo = NULL; return item; } int listarobots_insere(listarobots *lst, const char* valor, int x, int y,int id) { robot_lista *curr = NULL, *temp; if (lst == NULL) return -1; temp = lst->raiz; /* cria novo item */ curr = novorobot_str(valor, x, y, id); if (curr == NULL) return -1; lst->tamanho++; curr->proximo = temp; lst->raiz = curr; return 1; } int listarobot_pesquisa(listarobots *lst, const char* str, int* x, int* y, int *id) { int i=0; robot_lista *aux; if(lst == NULL) return -1; /* pesquisa sequencial */ for (aux = lst->raiz; aux != NULL; aux = aux->proximo, i++) { if (strcmp((aux->nome), str) == 0) { *x= aux->x; *y= aux->y; *id= aux->id; return i; } } return -1; } int listarobot_atribui(listarobots *lst, int pos, int x, int y) { int i=0; robot_lista *aux; if (lst == NULL || pos < 0) return -1; aux = lst->raiz; /* procura item na posicao pos */ for (i = 0; i < pos && aux != NULL; i++) aux = aux->proximo; /* se aux e' NULL entao nao existe posicao pos */ if (aux == NULL) return -1; aux->x=x; aux->y=y; return pos; } lista* lista_nova() { /* cria lista */ lista *lst = (lista*) malloc(sizeof(lista)); if(lst == NULL) return NULL; /* lista esta' vazia */ lst->raiz = NULL; lst->tamanho = 0; return lst; } elemento_lista* novo_str(int x, int y, int v) { /* aloca memoria para a estrutura lista */ elemento_lista *item = (elemento_lista *) malloc(sizeof(elemento_lista)); if(item == NULL) return NULL; item->v=v; item->x=x; item->y=y; /* item ainda nao tem proximo */ item->proximo = NULL; return item; } int lista_insere(lista *lst, int x, int y, int v) { elemento_lista *curr = NULL, *temp; if (lst == NULL) return -1; temp = lst->raiz; /* cria novo item */ curr = novo_str(x,y,v); if (curr == NULL) return -1; lst->tamanho++; curr->proximo = temp; lst->raiz = curr; return v; } int lista_pesquisa(lista *lst, int x, int y) { int i=0; elemento_lista *aux; if(lst == NULL) return -1; /* pesquisa sequencial */ for (aux = lst->raiz; aux != NULL; aux = aux->proximo, i++) { if ((aux->x==x) && (aux->y==y)) { return aux->v; } } return -1; } int lista_xy (lista *lst, int v, int *x , int* y) { int i=0; elemento_lista *aux; if(lst == NULL) return -1; /* pesquisa sequencial */ for (aux = lst->raiz; aux != NULL; aux = aux->proximo, i++) { if ((aux->v==v)) { *x=aux->x; *y=aux->y; return 1; } } return -1; } void leitura(int *tamx,int *tamy,int *xminfinal, int* yminfinal, int *wx, int *wy, int *fimx, int *fimy, FILE * fp, grafo *robots, lista *celulas, listarobots *posicoes) { int naofaznada,tamanho=0, i, x, y, xmax, xmin, ymax, ymin, v=1,dest,poslst, origem,id=0; char nome[16], aux; xmax=xmin=ymax=ymin=0; celulas=lista_nova(); lista_insere(celulas, 0,0,0); fp = fopen("input.txt", "r"); robots = grafo_novo(tamanho,NAODIRECIONADO); posicoes=listarobots_nova(); fscanf( fp, " %c", &aux); while (aux!=EOF) { for (i=0;aux!= ',';i++) { nome[i]=aux; nome[i+1]='\0'; fscanf(fp, " %c", &aux); } fscanf(fp, " %c", &aux); poslst=listarobot_pesquisa(posicoes, nome, &x, &y, &naofaznada); if(poslst==-1) { if(aux=='D') { x=0; y=-1; } if(aux=='U') { x=0; y=1; } if(aux=='L') { x=-1; y=0; } if(aux=='R') { x=1; y=0; } listarobots_insere(posicoes, nome, x, y, id); id++; origem=0; if(x>xmax) xmax=x; if(x<xmin) xmin=x; if(y>ymax) ymax=y; if(y<ymin) ymin=y; if(lista_pesquisa(celulas, x, y)==-1) { lista_insere(celulas, x, y, v); dest=v; v++; grafo_adiciona(robots, 0, dest); if(lista_pesquisa(celulas, (x+1),y)!=-1) grafo_adiciona(robots, dest, lista_pesquisa(celulas, (x+1), y)); if(lista_pesquisa(celulas, (x-1),y)!=-1) grafo_adiciona(robots, dest, lista_pesquisa(celulas, (x-1), y)); if(lista_pesquisa(celulas, x,(y+1))!=-1) grafo_adiciona(robots, dest, lista_pesquisa(celulas, x, (y+1))); if(lista_pesquisa(celulas, x,(y-1))!=-1) grafo_adiciona(robots, dest, lista_pesquisa(celulas, x, (y-1))); } } else { origem=lista_pesquisa(celulas,x, y); if(aux=='D') { y=y-1; } if(aux=='U') { y=y+1; } if(aux=='L') { x=x-1; } if(aux=='R') { x=x+1; } listarobot_atribui(posicoes, poslst, x, y); } if(x>xmax) xmax=x; if(x<xmin) xmin=x; if(y>ymax) ymax=y; if(y<ymin) ymin=y; if(lista_pesquisa(celulas, x, y)==-1) { lista_insere(celulas, x, y, v); dest=v; v++; grafo_adiciona(robots, origem, dest); if(lista_pesquisa(celulas, (x+1),y)!=-1) grafo_adiciona(robots, dest, lista_pesquisa(celulas, (x+1), y)); if(lista_pesquisa(celulas, (x-1),y)!=-1) grafo_adiciona(robots, dest, lista_pesquisa(celulas, (x-1), y)); if(lista_pesquisa(celulas, x,(y+1))!=-1) grafo_adiciona(robots, dest, lista_pesquisa(celulas, x, (y+1))); if(lista_pesquisa(celulas, x,(y-1))!=-1) grafo_adiciona(robots, dest, lista_pesquisa(celulas, x, (y-1))); } if(fscanf(fp, " %c", &aux)==EOF) break; if(aux=='?') { *wx=x; *wy=y; if(fscanf(fp, " %c", &aux)==EOF) break; } if(aux=='!') { *fimx=x; *fimy=y; if(fscanf(fp, " %c", &aux)==EOF) break; } } *tamx= xmax-xmin+1; *tamy= ymax-ymin +1; *xminfinal=xmin; *yminfinal=ymin; return ; } void mapeamento(FILE * out, int x, int y, int ymin, int xmin, int wx, int wy, int fimx, int fimy, lista* celulas ) { int xatual, yatual; for(yatual=ymin+ y-1; yatual!=ymin-1;yatual--) { for(xatual=xmin; xatual!=xmin+x; xatual++) { if((xatual==0) && (yatual==0)) fprintf(out," e "); else if((xatual==wx)&&(yatual==wy)) fprintf(out, " w "); else if((xatual==fimx)&&(yatual==fimy)) fprintf(out, " s "); else if(lista_pesquisa(celulas, x, y)==-1) fprintf(out, " * "); else if(lista_pesquisa(celulas, x, y)!=-1)fprintf(out, " . "); if(xatual==fimx) fprintf(out, "\n"); } } return; } void caminhos(int wx, int wy, int fimx, int fimy, lista* celulas, FILE *fp, FILE *out, grafo *robots, listarobots* posicoes) { int restantes,nfnx,nfny,i,id,is,antx,anty,novox,novoy,tamanhocaminho1,tamanhocaminho2, *caminho1, *caminho2, *posrobots; char *caminho,nome[16], aux; caminho1=grafo_bfs(robots, 0, lista_pesquisa(celulas, wx, wy), &tamanhocaminho1); caminho2=grafo_bfs(robots, lista_pesquisa(celulas, wx, wy), lista_pesquisa(celulas, fimx, fimy), &tamanhocaminho2); caminho= malloc((tamanhocaminho1+tamanhocaminho2)*sizeof(char)); antx=0; anty=0; is=0; for(i=1; i<tamanhocaminho1; i++, is++) { lista_xy(celulas, caminho1[i], &novox, &novoy); if((novox-antx)==1) caminho[is]= 'R'; else if((novox-antx)==-1) caminho[is]= 'L'; else if((novoy-anty)==-1) caminho[is]= 'D'; else if((novoy-anty)==1) caminho[is]= 'U'; antx=novox; anty=novoy; } for(i=1; i<tamanhocaminho2; i++, is++) { lista_xy(celulas, caminho1[i], &novox, &novoy); if((novox-antx)==1) caminho[is]= 'R'; else if((novox-antx)==-1) caminho[is]= 'L'; else if((novoy-anty)==-1) caminho[is]= 'D'; else if((novoy-anty)==1) caminho[is]= 'U'; antx=novox; anty=novoy; } caminho[is]='\0'; fprintf(out, "\n\n%s\n", caminho); free(caminho1); free(caminho2); fclose(fp); fp=fopen("input.txt", "r"); restantes=posicoes->tamanho; posrobots=calloc (posicoes->tamanho, sizeof(int)); fscanf(fp, " %c", &aux); while (aux!=EOF) { for (i=0;aux!= ',';i++) { nome[i]=aux; nome[i+1]='\0'; fscanf(fp, " %c", &aux); } fscanf(fp, " %c", &aux); listarobot_pesquisa(posicoes, nome, &nfnx, &nfny, &id); if(posrobots[id]==-1) nfnx=1; else if(caminho[posrobots[id]]==aux) posrobots[id]++; else { posrobots[id]=-1; restantes--; } if(posrobots[id]==is) fprintf(out, "%s\n", nome); fscanf(fp, " %c", &aux); if(aux=='?') { fscanf(fp, " %c", &aux); } if(aux=='!') { fscanf(fp, " %c", &aux); } } if(restantes==0) fprintf(out, "0\n"); } void output() { } int main() { FILE *fp, *out; grafo *robots; lista *celulas; listarobots *posicoes; celulas=(lista * )malloc(sizeof(lista)); robots=(grafo * )malloc(sizeof(grafo)); posicoes=(listarobots * )malloc(sizeof(listarobots)); fp=(FILE * )malloc(sizeof(FILE)); out=(FILE * )malloc(sizeof(FILE)); int x,y,xmin, ymin,wx,wy,fimx,fimy; out=fopen("output.txt", "w"); leitura(&x, &y, &xmin, &ymin,&wx, &wy, &fimx, &fimy, fp, robots, celulas, posicoes); fprintf(out,"largura:%d, altura:%d\n", x, y ); mapeamento(out, x, y, ymin, xmin, wx, wy, fimx, fimy, celulas); //caminhos(wx, wy,fimx, fimy,celulas, fp, out, robots, posicoes); return 0; } the extra includes dont make a difference, I've checked and the errors are on this block of code, but just in case, I'll post here the code for the include "grafo.h" #include <stdio.h> #include <stdlib.h> #include "grafo.h" /* cria no da lista de adjacencias */ lista_no* cria_no(int v) { lista_no* novo = (lista_no*)malloc(sizeof(lista_no)); if(!novo) return NULL; novo->vertice = v; novo->proximo = NULL; return novo; } /* cria grafo com n vertices */ grafo* grafo_novo(int n, tipo_grafo tipo) { grafo* g = (grafo*)malloc(sizeof(grafo)); lista_no novo; if(g == NULL) return NULL; g->tamanho = 1; g->tipo = tipo; /* cria array de listas de adjacencias */ g->adjacencias = (lista_adj*)calloc(n, sizeof(lista_adj)); if(g->adjacencias == NULL) { free(g); return NULL; } g->adjacencias[0].inicio=NULL; return g; } /* apaga grafo e liberta memoria */ void grafo_apaga(grafo* g) { if(g == NULL) return; if(g->adjacencias != NULL) { int v; for (v = 0; v < g->tamanho; v++) { while (g->adjacencias[v].inicio) { lista_no* aux = g->adjacencias[v].inicio; g->adjacencias[v].inicio = g->adjacencias[v].inicio->proximo; free(aux); } } free(g->adjacencias); } free(g); } /* adiciona uma aresta ao grafo*/ void grafo_adiciona(grafo *g, int origem, int dest) { lista_no* novo,*aux,*ant; if (g == NULL || grafo_existe(g, origem, dest)) return; /* adiciona uma aresta de origem para dest na lista de adjacencias */ novo = cria_no(dest); novo->proximo = NULL; g->adjacencias = (lista_adj*)realloc(g->adjacencias, (g->tamanho+1)*sizeof(lista_adj)); g->adjacencias[dest].inicio=NULL; g->tamanho++; ant= aux =g->adjacencias[origem].inicio; if(ant==NULL) g->adjacencias[origem].inicio=novo; else { aux=ant->proximo; while(aux!=NULL) { ant=aux; aux=ant->proximo; } ant->proximo=novo; } g->adjacencias[origem].tamanho++; if(g->tipo == NAODIRECIONADO) { /* adiciona tambem aresta de dest para origem */ novo = cria_no(origem); novo->proximo = NULL; ant= aux =g->adjacencias[dest].inicio; if(ant==NULL) g->adjacencias[dest].inicio=novo; else { aux=ant->proximo; while(aux!=NULL) { ant=aux; aux=ant->proximo; } ant->proximo=novo; } g->adjacencias[dest].tamanho++; } } /* remove uma aresta do grafo*/ void grafo_remove(grafo *g, int origem, int dest) { lista_no *aux, *prev; if (g == NULL || g->adjacencias[origem].inicio == NULL) return; aux = g->adjacencias[origem].inicio; /* caso especial: primeiro no' da lista */ if(aux->vertice == dest) { g->adjacencias[origem].inicio = aux->proximo; free(aux); } else { prev = aux; aux = aux->proximo; while(aux != NULL) { if(aux->vertice == dest) { prev->proximo = aux->proximo; free(aux); break; } prev = aux; aux = aux->proximo; } } if(g->tipo == NAODIRECIONADO) { /* remove tambem aresta de dest para origem */ /* caso especial: primeiro no' da lista */ aux = g->adjacencias[dest].inicio; if(aux->vertice == origem) { g->adjacencias[dest].inicio = aux->proximo; free(aux); } else { prev = aux; aux = aux->proximo; while(aux != NULL) { if(aux->vertice == origem) { prev->proximo = aux->proximo; free(aux); break; } prev = aux; aux = aux->proximo; } } } } /* verifica se existe uma aresta entre os vertices origem e dest */ int grafo_existe(grafo *g, int origem, int dest) { if (g == NULL) return 0; lista_no* aux = g->adjacencias[origem].inicio; while (aux) { if(aux->vertice == dest) return 1; aux = aux->proximo; } return 0; } /* imprime as listas de adjacencias do grafo */ void grafo_imprime(grafo* g) { int i; for (i = 0; i < g->tamanho; i++) { lista_no* aux = g->adjacencias[i].inicio; printf("%d: ", i); if(aux) { printf("%d", aux->vertice); aux = aux->proximo; while (aux) { printf("->%d", aux->vertice); aux = aux->proximo; } } printf("\n"); } } int dfs_helper(grafo *g, int inicio, int fim, int profundidade, int *visitados) { int i, d; if(visitados[inicio]) return 0; visitados[inicio] = profundidade; if(inicio == fim) return profundidade; for(i=0; i < g->tamanho; i++) { if(grafo_existe(g, inicio, i)) { d = dfs_helper(g, i, fim, profundidade + 1, visitados); if(d) return d; } } visitados[inicio] = 0; return 0; } /* retorna caminho entre origem e dest usando depth-first search (DFS) n guarda o tamanho do caminho nao garante caminho mais curto */ int* grafo_dfs(grafo *g, int inicio, int fim, int *n) { int *visitados, *caminho; int profundidade, i, ret_i; if(g==NULL) return 0; visitados = calloc(g->tamanho, sizeof(int)); profundidade = dfs_helper(g, inicio, fim, 1, visitados); if(profundidade == 0) { free(visitados); *n=0; return NULL; } /* reconstrucao do caminho */ caminho = calloc(profundidade, sizeof(int)); for (ret_i = 0; ret_i < profundidade; ret_i++) for (i = 0; i< g->tamanho; i++) if(visitados[i] == ret_i + 1) { caminho[ret_i] = i; break; } *n = profundidade; free(visitados); return caminho; } /* retorna caminho entre origem e dest usando breadth-first search (BFS) n guarda o tamanho do caminho garante caminho mais curto */ int* grafo_bfs(grafo *g, int inicio, int fim, int *n) { int *caminho, *visitados, *fila; int profundidade, i, j, fila_inicio = 0, fila_fim=0; if(g==NULL) return 0; visitados = calloc(g->tamanho, sizeof(int)); fila = calloc(g->tamanho, sizeof(int)); for(i = 0; i < g->tamanho; i++) visitados[i] = -1; visitados[inicio] = inicio; fila[fila_fim++] = inicio; while(fila_inicio != fila_fim) { i = fila[fila_inicio]; fila_inicio = (fila_inicio + 1) % g->tamanho; for(j = 0; j < g->tamanho; j++) if(grafo_existe(g, i, j) && visitados[j] == -1) { visitados[j] = i; fila[fila_fim] = j; fila_fim = (fila_fim + 1) % g->tamanho; } } /* reconstrucao do caminho */ profundidade = 0; if(visitados[fim] >= 0) { int tmp = fim; profundidade = 1; while(visitados[tmp] != tmp) { profundidade++; tmp = visitados[tmp]; } caminho = malloc(profundidade * sizeof(int)); tmp = fim; i = 0; while(i++ < profundidade) { caminho[profundidade - i] = tmp; tmp = visitados[tmp]; } } free(fila); free(visitados); *n=profundidade; return caminho; } And the warnings are: Description Resource Path Location Type assignment from incompatible pointer type [enabled by default] trabalho.c /trabalho/src line 110 C/C++ Problem assignment from incompatible pointer type [enabled by default] trabalho.c /trabalho/src line 135 C/C++ Problem assignment from incompatible pointer type [enabled by default] trabalho.c /trabalho/src line 95 C/C++ Problem I appreciate any and all the help you can offer. I am still pretty new at programming and this warnings are completely messing with my mind.
It looks like you're assigning proximo (which are pointers to _elemento) to variables that are pointers to robot_lista.