nested linked lines

Hi there!

First of all: I'm writing in pure C language. With this put, let's get to the problem! ;)

I have a linked line of workers and each worker has a linked line of jobs. The problem is that I just can't access the jobs lines. When I try to use a value or even print something from this line, I get this message from the debugger:

Unhandled exception at 0x00432b72 in Servidor.exe: 0xC0000005: Access violation reading location 0x0000001e.

First, I had a pointer to the job line in the worker structure:

struct TRABALHADOR {
int id;
char nome[25];
unsigned short porta;
SOCKET sockComunicacao;
SOCKET sockControle;

struct FilaDeTarefas * raizFilaDeTarefasIndividual; //this is the pointer.

int estado;
HANDLE trabalhadorPodeExecutar;
int numeroDeTarefasNaFila;
};

Since I couldn't insert or read any node to this line, I changed the structure: took the pointer from the worker structure and put it on the worker line structure:

struct FilaDeTrabalhadores {
struct TRABALHADOR trabalhador;
struct Fila * prox;

struct FilaDeTarefas * raizFilaDeTarefasIndividual; //the pointer is here now.
} filaTrabalhadores;

But I had the same result. Does anyone have a clue of what is happening? I'd be very pleased if there are any guesses!

ps: I'm not sure if some terms are right in english, but I guess everyone can understand the text. Thanks in advance!
[1546 byte] By [danmartins] at [2007-11-20 2:59:55]
# 1 Re: nested linked lines
You don't show the code initializing the pointer fields (make them point to memory blocks).
The runtime error says that you've fetched a value from location 0x1e
It's perhaps the value of the uninitialized pointer.

Could you show the code?
SuperKoko at 2007-11-9 1:10:12 >
# 2 Re: nested linked lines
I don't think you have a structure problem.
The problems seems to be related with an uninitialized pointer.

If you see the address showed in the AccessExceptions, you will see that is a value near to zero. Surely, that is garbage storaged in the pointer previous to an initialization, because, that kind of addresses (very low addresses) are used by the system.

You must looking for initialization of pointers and find one without an initialization (previous to it use)
Carlos Martinez at 2007-11-9 1:11:09 >
# 3 Re: nested linked lines
If I do this, shouldn't it be working?

struct TAREFA tarefa;
struct FilaDeTarefas * novatarefa;

tarefa.id = -99;
novatarefa = malloc(sizeof(filaDeTarefas));
novatarefa->prox = NULL;
novatarefa->tarefa = tarefa;

raizFilaDeTrabalhadores->raizFilaDeTarefasIndividual = novatarefa;
danmartins at 2007-11-9 1:12:13 >
# 4 Re: nested linked lines
If I do this, shouldn't it be working?

struct TAREFA tarefa;
struct FilaDeTarefas * novatarefa;

tarefa.id = -99;
novatarefa = malloc(sizeof(filaDeTarefas));
novatarefa->prox = NULL;
novatarefa->tarefa = tarefa;

raizFilaDeTrabalhadores->raizFilaDeTarefasIndividual = novatarefa;

There is no code enough.
novatarefa has a valid pointer, but if the exception is thrown at the last line, the problem is raizFilaDeTrabalhadores pointer. Where is it initialized?
Carlos Martinez at 2007-11-9 1:13:08 >
# 5 Re: nested linked lines
If I do this, shouldn't it be working?

struct TAREFA tarefa;
struct FilaDeTarefas * novatarefa;

tarefa.id = -99;
novatarefa = malloc(sizeof(filaDeTarefas));
novatarefa->prox = NULL;
novatarefa->tarefa = tarefa;

raizFilaDeTrabalhadores->raizFilaDeTarefasIndividual = novatarefa;
What's the raizFilaDeTrabalhadores variable in this piece of code?
SuperKoko at 2007-11-9 1:14:10 >
# 6 Re: nested linked lines
There is no code enough.
novatarefa has a valid pointer, but if the exception is thrown at the last line, the problem is raizFilaDeTrabalhadores pointer. Where is it initialized?

What's the raizFilaDeTrabalhadores variable in this piece of code?

raizFilaDeTrabalhadores is the root of the first linked line, the workers line. I don't have any problems with this line.
Also, the exception isn't thrown at that line, it's thrown at this line:

printf("\n\n\n\n\n.....[%d] it's the job ID", aux->raizFilaDeTarefasIndividual->tarefa.id); which comes just after what I posted before.

Is invalid, since the tarefa member of novatarefa is not initialized.

How would I initialize it?
danmartins at 2007-11-9 1:15:09 >
# 7 Re: nested linked lines
printf("\n\n\n\n\n.....[%d] it's the job ID", aux->raizFilaDeTarefasIndividual->tarefa.id); which comes just after what I posted before.


If exception is thrown at that line then you have a problem with aux or with raizFilaDeTarefasIndividual of aux. Use a debugger for determine which pointer is unitialized.

I must say you again "Please, post more code". We can't see initialization of your pointers in the code you post.
Carlos Martinez at 2007-11-9 1:16:13 >
# 8 Re: nested linked lines
If exception is thrown at that line then you have a problem with aux or with raizFilaDeTarefasIndividual of aux. Use a debugger for determine which pointer is unitialized.

I must say you again "Please, post more code". We can't see initialization of your pointers in the code you post.

Yes, I guess the problem is with raizFilaDeTarefasIndividual, which is the pointer for the jobs linked line.
Sorry for the unsuficient code, I thought it would be enough. I'll try to put it all now:

struct TRABALHADOR trabalhador;

trabalhador.sockComunicacao = accept(sockListenSRV,(struct sockaddr*)&from, &fromlen);
trabalhador.sockControle = accept(sockListenSRVIsAlive,(struct sockaddr*)&fromIsAlive, &fromlenIsAlive);

if (trabalhador.sockComunicacao == INVALID_SOCKET ) {
printf("\n\nErro no accept()1 %d\n",WSAGetLastError());
WSACleanup();
return -1;
}
if (trabalhador.sockControle == INVALID_SOCKET ) {
printf("\n\nErro no accept()2 %d\n",WSAGetLastError());
WSACleanup();
return -1;
}
else {

strcpy(trabalhador.nome, inet_ntoa(from.sin_addr));
trabalhador.porta = htons(from.sin_port);
trabalhador.id = numTrabalhadores;
trabalhador.trabalhadorPodeExecutar = CreateEvent(NULL, FALSE, FALSE, NULL);

insereTrabalhador(trabalhador);

/*
first I detect a worker, set it's properties, and then call a function to insert it into to the linked line.
*/

void insereTrabalhador(struct TRABALHADOR trabalhador) {
struct FilaDeTrabalhadores * novo;
struct FilaDeTrabalhadores * aux;


struct TAREFA tarefa;
struct FilaDeTarefas * novatarefa;

/*
Down Mutex of workers line
*/
WaitForSingleObject(mutexFilaDeTrabalhadores, INFINITE); //Down Mutex



tarefa.id = -99;

novatarefa = malloc(sizeof(filaDeTarefas));
novatarefa->prox = NULL;
novatarefa->tarefa = tarefa;

/*
on the original code, the allocation of the second linked line shouldn't be here, but i think it'll be easier if I can solve the problem here and then work it else where*/

novo = malloc(sizeof(filaTrabalhadores));
novo->prox = NULL;
novo->trabalhador = trabalhador;

aux = raizFilaDeTrabalhadores;
if (raizFilaDeTrabalhadores == NULL) {
raizFilaDeTrabalhadores = novo;
raizFilaDeTrabalhadores->raizFilaDeTarefasIndividual = novatarefa;

}
else {
while(aux->prox != NULL) {
aux = aux->prox;
}
aux->prox = novo;
aux->raizFilaDeTarefasIndividual = novatarefa;
}

/*
Uo Mutex of workers line
*/
SetEvent(mutexFilaDeTrabalhadores); //Up Mutex

numTrabalhadores ++;
printf("\nNumero de Trabalhadores: %d", numTrabalhadores);

printf("\n\n\n\n\n.....[%d] it's the job ID", aux->raizFilaDeTarefasIndividual->tarefa.id);

Is this code understandable?
danmartins at 2007-11-9 1:17:18 >
# 9 Re: nested linked lines
/*
on the original code, the allocation of the second linked line shouldn't be here, but i think it'll be easier if I can solve the problem here and then work it else where*/

novo = malloc(sizeof(filaTrabalhadores));
novo->prox = NULL;
novo->trabalhador = trabalhador;

aux = raizFilaDeTrabalhadores;
if (raizFilaDeTrabalhadores == NULL) {
raizFilaDeTrabalhadores = novo;
raizFilaDeTrabalhadores->raizFilaDeTarefasIndividual = novatarefa;

}
else {
while(aux->prox != NULL) {
aux = aux->prox;
}
aux->prox = novo;
aux->raizFilaDeTarefasIndividual = novatarefa;
}

I supose raizFilaDeTrabalhadores to be a global variable (I haven't see declared inside the function).
I don't know what is its value. I suppose to be NULL for the first time and a valid pointer value for the subsequent passes.

Imagine raizFilaDeTrabalhadores is NULL.
When program executes:
aux = raizFilaDeTrabalhadores;

aux is set to value of raizFilaDeTrabalhadores (with a NULL value)

After that raizFilaDeTrabalhadores is set to novo (because is the first node), but aux continue with a NULL value. If you assign a value to raizFilaDeTrabalhadores it is not copied automatically to aux. You have aux with NULL

printf("\n\n\n\n\n.....[%d] it's the job ID", aux->raizFilaDeTarefasIndividual->tarefa.id);

aux is NULL, then you have an access violation.

I have supposed raizFilaDeTrabalhadores to be NULL for this example, but in your case it seems to be uninitialized, and you have 0x0000001e instead of NULL.
Carlos Martinez at 2007-11-9 1:18:19 >
# 10 Re: nested linked lines
Carlos, you seem to be very smart! :D you got it all right: raizFilaDeTrabalhadores is a global variable, indicating the first node of the workers line and it does starts with a NULL value. I have no problems with this line, only with the line of jobs, which is a property of each node of the workers line. What I don't understand is that I'm doing the same thing (initialization, insertion, etc) with both lines, but the job lines won't work...
let's go to your suggestion:

After that raizFilaDeTrabalhadores is set to novo (because is the first node), but aux continue with a NULL value. If you assign a value to raizFilaDeTrabalhadores it is not copied automatically to aux. You have aux with NULL

It does makes sense, but if that was the problem, the problem should be solved if I use "raizFilaDeTrabalhadores" instead of "aux". right?

printf("\n\n\n\n\n.....[%d] it's the job ID", raizFilaDeTrabalhadores->raizFilaDeTarefasIndividual->tarefa.id);

But it doesn't work... debugger sends me the same message:

Unhandled exception at 0x00432b72 in Servidor.exe: 0xC0000005: Access violation reading location 0x0000001e.

:( :( :(
danmartins at 2007-11-9 1:19:11 >
# 11 Re: nested linked lines
It does makes sense, but if that was the problem, the problem should be solved if I use "raizFilaDeTrabalhadores" instead of "aux". right?

printf("\n\n\n\n\n.....[%d] it's the job ID", raizFilaDeTrabalhadores->raizFilaDeTarefasIndividual->tarefa.id);

But it doesn't work... debugger sends me the same message:

Unhandled exception at 0x00432b72 in Servidor.exe: 0xC0000005: Access violation reading location 0x0000001e.

Yes, you're right, you have a problem with aux but if with raizFilaDeTrabalhadores you have the same problem, the cause is another error, unless raizFilaDeTrabalhadores is not initialized to NULL (at the first pass).

I don't see any other bug. I suggest you to use a debugger or to trace pointers' value. You will obtain two important consecuences:
-You will see which is the concrete pointer pointing to 0x000001e
-You will see when is set to that value.

I cannot test for you because I haven't complete code nor a microsoft C compiler.

I'm sorry, I cannot locate the bug in your code.
Carlos Martinez at 2007-11-9 1:20:17 >
# 12 Re: nested linked lines
Carlos,

thanks anyways. I'll try to work it out and then I'll post the solution. :D
danmartins at 2007-11-9 1:21:18 >
# 13 Re: nested linked lines
void insereTrabalhador(struct TRABALHADOR trabalhador) {
struct FilaDeTrabalhadores * novo;
struct FilaDeTrabalhadores * aux;


struct TAREFA tarefa;/* warning this tarefa structure is initialized to garbage values */
struct FilaDeTarefas * novatarefa;

/*
Down Mutex of workers line
*/
WaitForSingleObject(mutexFilaDeTrabalhadores, INFINITE); //Down Mutex



tarefa.id = -99;/* well, now tarefa has an id... The same for all*/

novatarefa = malloc(sizeof(filaDeTarefas)); /* you should test for the return value of malloc */
novatarefa->prox = NULL;
novatarefa->tarefa = tarefa;

/*
on the original code, the allocation of the second linked line shouldn't be here, but i think it'll be easier if I can solve the problem here and then work it else where*/

novo = malloc(sizeof(filaTrabalhadores));
novo->prox = NULL;
novo->trabalhador = trabalhador;

aux = raizFilaDeTrabalhadores;
if (raizFilaDeTrabalhadores == NULL) {
raizFilaDeTrabalhadores = novo;
raizFilaDeTrabalhadores->raizFilaDeTarefasIndividual = novatarefa; /* you should move this assignment just after the novo->trabalhador = trabalhador; line; It would be far easier to read the code */

}
else {
while(aux->prox != NULL) { /* why do you put the element at the end of the list and not at the beginning ? */
aux = aux->prox;
}
aux->prox = novo;
aux->raizFilaDeTarefasIndividual = novatarefa;/* you should move this assignment just after the novo->trabalhador = trabalhador; line */

}

/*
Uo Mutex of workers line
*/
SetEvent(mutexFilaDeTrabalhadores); //Up Mutex
/* This is a MAJOR bug, the SetEvent function excepts an event handle, not a mutex handle. You should use ReleaseMutex*/

numTrabalhadores ++;
printf("\nNumero de Trabalhadores: %d", numTrabalhadores);

printf("\n\n\n\n\n.....[%d] it's the job ID", aux /* replace this variable reference with novo */->raizFilaDeTarefasIndividual->tarefa.id);
SuperKoko at 2007-11-9 1:22:17 >