Hi All,
I'm actually making a little program but I'm encountering an error that I can't manage to resolve.
So I have a linked list of "User" (each User has got a pointer to the previous User and another pointer to the next User). At First, the List is empty and initialized by the UserInit function. The 2 global User First and Last are pointing on each other as there is at this moment no real User.
At the line 73-77 : I allocate five new User
At the line 113-122 : I put a name in the 'surnom' variable and I add the User in the List.
At the line 97-105 : In the meantime, I made 10 threads that will each add 10 Users to the List.
The Problem : The function AfficheList is working great and shows all the Users lying in the List so the link between each User is correct (good pointer on good User).
When I want do delete (using the DeleteUser function) an User, there is no problem for the five Users allocated in the main (un,deux,trois,quatre,cinq "User") BUT if I want to delete any of the 100 Users allocated by the threads . . . it's ALWAYS getting me an error on the free of the concerned User . . . I verified that each adress lying in the next or previous part of the User is the good one and this is the case !
So I hope someone of you will try to help me !
Thank you !:icon_wink:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <string.h>
#include <pthread.h>
#include <signal.h>
#include "semadd.h"
#define MAXCHAR 25
struct User
{
struct User *prev;
char surnom[MAXCHAR];
char motdepasse[MAXCHAR];
int handle;
char nomsalon[MAXCHAR];
struct User *next;
};
void UserInit(void);
int AddUser(struct User *);
struct User* SearchUser(char *);
int DeleteUser(char *);
void AfficheListe(void);
void* fctThread(struct User *);
void* SynchroThread(void*);
void traitement_signal(int);
pthread_t MonThread[10];
pthread_t Synchronisation;
int Sem1;
int Sem2;
struct sigaction sigAct;
struct User First;
struct User Last;
void traitement_signal(int signum)
{
int i = 0;
printf("SIGINT recu !\n");
struct User *Temp;
struct User *Old;
struct User *ToDelete;
while(First.next != &Last)
{
printf("yop ! ! ! \n");
DeleteUser("");
}
/*printf("yop ! \n");
Old = Last.prev;
Temp = Temp->prev;
free(Old);
Last.prev = Temp;*/
}
int main (void)
{
int i=0;
int a=0;
int errno = 0;
int *test;
struct User *PUser;
struct User *un,*deux,*trois,*quatre,*cinq;
un = malloc(sizeof(struct User));
deux = malloc(sizeof(struct User));
trois = malloc(sizeof(struct User));
quatre = malloc(sizeof(struct User));
cinq = malloc(sizeof(struct User));
sigemptyset(&sigAct.sa_mask);
sigAct.sa_handler=traitement_signal;
sigaction(SIGINT,&sigAct,NULL);
Sem1 = sem_transf(12345);
Sem2 = sem_transf(67890);
UserInit();
errno = pthread_create(&Synchronisation, NULL,(void *(*)(void *))SynchroThread,(void*)i);
if (errno)
{
printf("ERREUR; code de retour pthread_create() est %d\n", errno);
}
for(i=0; i<10 ; i++)
{
PUser = malloc(10 * sizeof(struct User));
errno = pthread_create(&MonThread[i], NULL,(void *(*)(void *))fctThread,PUser);
if (errno)
{
printf("ERREUR; code de retour pthread_create() est %d\n", errno);
}
}
for(i=0; i<10 ; i++)
{
pthread_join(MonThread[i],(void **)&errno);
}
strcpy(un->surnom ,"un");
AddUser(un);
strcpy(deux->surnom ,"deux");
AddUser(deux);
strcpy(trois->surnom ,"trois");
AddUser(trois);
strcpy(quatre->surnom ,"quatre");
AddUser(quatre);
strcpy(cinq->surnom ,"cinq");
AddUser(cinq);
AfficheListe();
DeleteUser(un->surnom);
DeleteUser(quatre->surnom);
DeleteUser(cinq->surnom);
printf("ici ?\n\n");
un = PUser->next;
DeleteUser(PUser->surnom);
printf("ici ?\n\n");
DeleteUser(un->surnom);
printf("ici ?\n\n");
AfficheListe();
getchar();
return 0;
}
void UserInit(void)
{
First.prev = NULL;
First.next = &Last;
Last.prev = &First;
Last.next = NULL;
}
int AddUser(struct User *UserRecu)
{
int i=0;
struct User *Temp;
Temp = &First;
while(Temp != NULL)
{
if(strcmp(Temp->surnom,UserRecu->surnom)==0)
{
i=1;
}
Temp = Temp->next;
}
Temp=&First;
if(i==0)
{
UserRecu->prev = &First;
UserRecu->next = Temp->next;
First.next = UserRecu;
Temp = Temp->next;
Temp = Temp->next;
Temp->prev = UserRecu;
return 1;
}
else
{
printf("Erreur : Surnom deja en cours d'utilisation ! \n");
return 0;
}
}
void AfficheListe(void)
{
int i=1;
struct User *Temp;
Temp = First.next;
printf("Liste d'User : \n");
while(Temp->next != NULL)
{
printf(" %d\n", Temp);
printf("%d -> %d %s %d\n", i,Temp->prev,Temp->surnom,Temp->next);
Temp = Temp->next;
i++;
}
}
struct User* SearchUser(char *surnom)
{
struct User *Temp;
Temp = &First;
while(Temp != NULL)
{
if(strcmp(Temp->surnom,surnom)==0)
{
return Temp;
}
Temp = Temp->next;
}
return NULL;
}
int DeleteUser(char *surnom)
{
struct User *Temp;
struct User *Old;
struct User *ToDelete;
Old = &First;
Temp = First.next;
while(Temp->next != NULL)
{
if(strcmp(Temp->surnom,surnom) == 0)
{
ToDelete = Temp;
Old->next = Temp->next;
Temp = Temp->next;
Temp->prev = Old;
free(ToDelete);
return 1;
}
Old = Temp;
Temp = Temp->next;
}
printf("Erreur : L'utilisateur n'a pu etre trouve !\n");
return 0;
}
void* fctThread(struct User *PUser)
{
int i=0;
int j=0;
int okay=1;
srand(time(NULL));
for(i=0;i<10;i++)
{
for(j=0;j<5;j++)
{
PUser->surnom[j] = rand() %26+'a';
}
PUser->surnom[j] = '\0';
PUser->handle = -1;
printf("User = %s\n", PUser->surnom);
p(Sem1);
okay = AddUser(PUser);
v(Sem2);
if(okay==1)
PUser++;
else
i--;
}
pthread_exit(NULL);
}
void* SynchroThread(void * a)
{
while(1)
{
v(Sem1);
p(Sem2);
}
pthread_exit(NULL);
}