-1
votes

C: Pointeur à Malloc'ed Heap Emplacement Plus 4

J'essaie de mettre en place un nouveau malloc qui stocke la taille à l'avant de la région de Malloc'ed, puis renvoie un pointeur à l'emplacement incrémenté (ce qui vient après l'INT non signé stocké).

result += sizeof(unsigned);


1 commentaires

Lorsque vous apprenez C, je recommanderais d'utiliser le compilateur GCC et de compiler toujours comme GCC -STD = C11-Erreurs -petic-erreurs -wall -wextra . De cette façon, vous ne vous retrouvez pas avec un code non standard discutable.


4 Réponses :


2
votes

résultat + = Tailleof (non signé); code> devrait vous donner au moins un avertissement (pointeur arithmétique sur VOID * code> conduit à un comportement non défini).

unsigned *result = malloc(size + sizeof size);
result[0] = size;
return result + 1;


1 commentaires

En fait, vous voulez probablement résultat pour être un pointeur sur l'union de Taille_t et max_align_t Pour assurer l'alignement ( max_align_t pourrait être plus large que uint64_t , même sur les plates-formes où le second est défini).



0
votes

Comment l'arithmétique du pointeur vide se produit dans GCC

C n'autorise pas l'arithmétique du pointeur avec un type de pointeur Void *. P>

gnu c le permet en considérant la taille de void code> est 1 code>. p> blockQuote>

Le résultat est code> est code> Void * code> donc résultat + = Tailleof (non signé); code> se trouve juste pour travailler sur des compilateurs compatibles. p>

Vous pouvez refactoriser votre fonction: p>

void *malloc_new(unsigned size) {
    void* result = malloc(size + sizeof(unsigned));
    ((unsigned*)result)[0] = size;
    result = (char*)result + sizeof(unsigned);
    return result;
}


0 commentaires

2
votes

Outre les problèmes notés dans d'autres réponses avec l'exécution de pointeur arithmétique sur Void * des pointeurs, vous violez probablement une des restrictions les lieux standard C sur la mémoire renvoyé des fonctions telles que < Code> malloc () .

7.22.3 Fonctions de gestion de la mémoire , paragraphe 1 de la norme C états:

La commande et la contiguïté du stockage attribuée par des appels successifs vers le aligné_alloc , calloc , malloc et realloc Les fonctions sont non spécifiées. Le pointeur est retourné si l'allocation réussie est alignée de manière appropriée afin qu'elle puisse être attribuée à un pointeur à tout type d'objet avec une exigence d'alignement fondamental, puis utilisé pour accéder à un tel objet ou à un éventail de tels objets dans l'espace alloué (jusqu'à ce que l'espace soit explicitement distribué). La durée de vie d'un objet attribué s'étend de la répartition jusqu'à la répartition. Chacune d'une telle allocation doit donner un pointeur à un objet disjoint d'un autre objet. Le pointeur a renvoyé des points au début (adresse d'octet la plus bas) de l'espace alloué. Si l'espace ne peut pas être alloué, un pointeur nul est renvoyé. Si la taille de l'espace demandé est zéro, le comportement est défini par la mise en œuvre: soit un pointeur NULL est renvoyé, ou le comportement est comme si la taille était une valeur non nulle, sauf que le pointeur renvoyé ne doit pas être utilisé pour accéder à un objet. .

Notez la partie en gras.

Sauf si votre système n'a qu'un alignement fondamental, que seulement quatre octets (8 ou 16 sont beaucoup plus typiques), vous enfreignez cette restriction et wil invoquez un comportement non défini par 6.3.2.3 Pointeurs , paragraphe 7 pour tout type d'objet avec une condition d'alignement fondamentale plus grande que quatre octets:

... Si le pointeur résultant n'est pas correctement aligné sur le type référencé, le comportement n'est pas défini. ...


0 commentaires

-1
votes

vous pouvez faire VOID * Arithmétique si Vous lancez le type d'abord au char *, par exemple. Puis jetez-le à vide *. Pour obtenir un meilleur alignement, utilisez un type 64 bits pour la taille, par exemple. uint64_t code>.

#define W_REF_VOID_PTR(ptr,offset) \
    ((void*)((char*) (ptr) + (offset)))


0 commentaires