Probleme d'ecrasement d'adresse par un pointeur
Bonjour,
j'ai un probleme d'ecrasement d'adresse par un pointeur dans un projet de double liste chainée allouée par des "block pool", je m'explique (accrochez vous)
- j'ai une structure comme tel et initialisée comme tel avec une macro :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| /// The block list element structure
struct block_list_elem
{
struct linked_list_elem list; ///< Block list element are linked list element
unsigned int size; ///< The element size
unsigned int read; ///< Index to read the data
unsigned int write; ///< Index to write the data
};
/// Initialise a block list element
/**
* \param elem A pointer to a linked list element.
*/
#define block_list_init_elem(elem) \
do \
{ \
linked_list_init_elem((struct block_list_elem *)(elem)); \
((struct block_list_elem *)(elem))->size = 0; \
((struct block_list_elem *)(elem))->read = 0; \
((struct block_list_elem *)(elem))->write = 0; \
} \
while(0) |
- une fonction write qui ecris dans des block de la liste chainée :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| void write( unsigned int data, struct block_list_head * head )
{
unsigned int data_size, size = 0;
ptr_data = NULL;
printf("\nWrite\n-------------------\n");
ptr_data = (unsigned int *)block_list_write_begin(head,&size); // Return the write pointer and the size to write
fprintf(stdout,"@ Write : %p\n",ptr_data);
fprintf(stdout," Size : %d\n",size);
*ptr_data = data;
fprintf(stdout,"@ Data : %p\n",ptr_data);
data_size = sizeof(data);
fprintf(stdout," Data size : %d\n",data_size);
block_list_write_end(head,data_size); // Move the write pointer
} |
- Une fonction Read qui lis les données :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| unsigned int read( struct block_list_head * head )
{
unsigned int data_size, size = 0;
ptr_data = NULL;
printf("\nRead\n-------------------\n");
ptr_data = (unsigned int *)block_list_read_begin(head,&size); // Return the read pointer and the size that can be read
fprintf(stdout,"@ Read : %p\n",ptr_data);
fprintf(stdout," Size : %d\n",size);
fprintf(stdout," Data : %d\n",*ptr_data);
data_size = sizeof(*ptr_data);
block_list_read_end(head,data_size); // Move the read pointer
return *ptr_data;
} |
- La fonction write appelle 2 fonctions : block_list_write_begin (renvoie le pointeur write et la taille possible a ecrire) et block_list_write_end (ajoute la taille de la donnée au pointeur write)
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| void *
block_list_write_begin( struct block_list_head * head, unsigned int * size )
{
struct block_list_elem * elem = NULL;
if (check(head != NULL, "Argument head is NULL"))
{
if (!linked_list_is_empty(head))
{
*size = head->free = block_list_get_size_written(head); // Compute the size to write
}
if (linked_list_is_empty(head) || (*size == 0)) // Check if the linked list is empty or Size = 0
{
elem = block_pool_alloc_as( block_list_elem, head->pool );
block_list_init_elem(elem);
linked_list_append_as( head, elem );
*size = head->free = block_list_get_size_written(head); // Compute the size to write
}
return block_list_get_write(head); // Return the write pointer
}
return NULL;
}
int
block_list_write_end( struct block_list_head * head, unsigned int size )
{
if (check(head != NULL, "Argument head is NULL") &&
check(size != 0, "Argument size is NULL"))
{
struct block_list_elem * elem = NULL;
elem = linked_list_last_as( block_list_elem, head );
elem->write += size;
return 0;
}
return -1;
} |
- La fonction read est similaire : elle appelle 2 fonctions block_list_read_begin (renvoie le pointeur read et la taille dispo que l'on peut lire) et block_list_read_end (decale le pointeur read quivant la taile que l'on a lue)
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| void *
block_list_read_begin( struct block_list_head * head, unsigned int * size )
{
if (check(head != NULL, "Argument head is NULL") &&
check(size != NULL, "Argument size is NULL"))
{
*size = head->free = block_list_get_size_read(head); // Compute the size to read
if (*size == 0) // There is nothing to read
{
*size = 0;
return NULL;
}
return block_list_get_read(head); // Return the read pointer
}
return NULL;
}
int
block_list_read_end( struct block_list_head * head, unsigned int size )
{
if (check(head != NULL, "Argument head is NULL") &&
check(size != 0, "Argument size is NULL"))
{
struct block_list_elem * elem = NULL;
elem = linked_list_first_as( block_list_elem, head );
elem->read += size;
if ( elem->read >= block_pool_size(head->pool) ) // The first block has been read , it must be removed
{
linked_list_unlink_as(elem);
block_pool_free( head->pool, elem );
}
return 0;
}
return -1;
} |
ces 4 fonctions font appels a 2 fonctions de calculs de taille (taille a lire et a ecrire) et 2 fonctions de retour de pointeur (lecture et ecriture vous l'aurez compris), je vous les met quand meme :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| /// Return the Read pointeur
void *
block_list_get_read( struct block_list_head * head )
{
struct block_list_elem * elem = NULL;
elem = linked_list_first_as( block_list_elem, head );
return (void *)((char *) elem + elem->read);
}
/// Return the Write pointeur
void *
block_list_get_write( struct block_list_head * head )
{
struct block_list_elem * elem = NULL;
elem = linked_list_last_as( block_list_elem, head );
return (void *)((char *) elem + elem->write);
}
/// Return the size that can be read
unsigned int
block_list_get_size_read( struct block_list_head * head )
{
struct block_list_elem * elem = NULL;
elem = linked_list_first_as( block_list_elem, head );
if ( elem->write > elem->read )
{
return ( elem->write - elem->read );
}
else
{
return 0;
}
} |
voila mon probleme est qu'a partir de 4 ecriture le pointeur elem->write retourné dans la fonction write (ptr_data donc) se place sur les autres membres de la structure elem (elem->list puis elem->read) etc ... vendant ecraser donc ces données.
le probleme viendrais surement du decalage que je fais a la fin d'une ecriture (block_list_write_end) ou j'ajoute la taille ecrite a la valeur elem->write.
je decale elem->write de la taille ecrite en unsigned int, cette valeur par de 0 etc ... et d'un autre coté dans block_list_get_write (retourne le pointeur write), je retourne l'adresse de elem + elem-write.
mais la je bloque c'est peu etre tout con mais je ne vois pas mon erreur :oops:
quelq'un pourrais t'il maider ? merci d'avance !