Comment obtenir la longueur du bloc de mémoire après malloc?

Je pensais que je ne pouvais pas récupérer la longueur d’un bloc de mémoire alloué comme la simple fonction .length en Java. Cependant, je sais maintenant que lorsque malloc() alloue le bloc, il atsortingbue des octets supplémentaires pour contenir un entier contenant la taille du bloc. Cet entier est situé au début du bloc; l’adresse effectivement renvoyée à l’appelant pointe vers l’emplacement situé juste après cette valeur de longueur. Le problème est que je ne peux pas accéder à cette adresse pour récupérer la longueur du bloc.

 #include  #include  int main(void) { char *str; str = (char*) malloc(sizeof(char)*1000); int *length; length = str-4; /*because on 32 bit system, an int is 4 bytes long*/ printf("Length of str:%d\n", *length); free(str); } 

** Edit: je l’ai finalement fait. Le problème est que cela donne 0 comme longueur, au lieu de la taille de mon système, car mon Ubuntu est en 64 bits. J’ai changé str-4 en str-8, et cela fonctionne maintenant.

Si je change la taille en 2000, cela produira 2017 comme longueur. Cependant, lorsque je passe à 3000, cela donne 3009. J’utilise GCC.

Ce que vous faites est définitivement faux. Bien qu’il soit presque certain que le mot situé juste avant le bloc alloué soit associé à la taille, il contient probablement des indicateurs ou des informations supplémentaires dans les bits inutilisés. Selon l’implémentation, ces données peuvent même se trouver dans les bits de poids fort , ce qui vous obligerait à lire une longueur totalement incorrecte. Il est également possible que des petites allocations (par exemple, de 1 à 32 octets) soient regroupées dans des pages spéciales de petits blocs sans en-tête, auquel cas le mot précédant le bloc atsortingbué ne fait que partie d’un autre bloc et n’a aucune signification par rapport à la taille. du bloc que vous examinez.

Juste arrêter cette poursuite égarée et dangereuse. Si vous avez besoin de connaître la taille d’un bloc obtenu par malloc , vous commettez une erreur.

Vous n’avez pas à le suivre par vous-même!

size_t malloc_usable_size (void * ptr);

Mais il retourne la taille réelle du bloc de mémoire alloué! Pas la taille que vous avez passée à malloc!

Je vous suggèrerais de créer votre propre wrapper malloc en compilant et en liant un fichier définissant my_malloc (), puis en modifiant la valeur par défaut comme suit:

 // my_malloc.c #define malloc(sz) my_malloc(sz) typedef struct { size_t size; } Metadata; void *my_malloc(size_t sz) { size_t size_with_header = sz + sizeof(Metadata); void* pointer = malloc(size_with_header); // cast the header into a Metadata struct Metadata* header = (Metadata*)pointer; header->size = sz; // return the address starting after the header // since this is what the user needs return pointer + sizeof(Metadata); } 

alors vous pouvez toujours récupérer la taille allouée en soustrayant sizeof (Metadata), en lançant ce pointeur sur Metadata et en effectuant metadata-> size:

 Metadata* header = (Metadata*)(ptr - sizeof(Metadata)); printf("Size allocated is:%lu", header->size); // don't quote me on the %lu ;-) 

Ce n’est pas de la version C. Cependant, il est supposé fonctionner sur les systèmes d’exploitation Windows et pourrait être disponible sur d’autres systèmes d’exploitation tels que Linux (msize?) Ou Mac (alloc_size?).

size_t _msize (void * memblock);

_msize () renvoie la taille d’un bloc de mémoire alloué dans le tas.

Voir ce lien: http://msdn.microsoft.com/en-us/library/z2s077bc.aspx

Vous n’êtes pas censé faire ça. Si vous voulez savoir combien de mémoire vous avez allouée, vous devez la garder vous-même.

Le fait de regarder en dehors du bloc de mémoire qui vous est renvoyé (avant le pointeur renvoyé par malloc ou après ce pointeur + le nombre d’octets que vous avez demandé) entraînera un comportement indéfini. Cela peut fonctionner dans la pratique pour une implémentation malloc donnée, mais ce n’est pas une bonne idée de dépendre de cela.

Ceci dépend de la mise en œuvre

Tu ferais mieux d’arrêter d’essayer de faire ce que tu fais!

Autant que je sache, le contenu de la mémoire avant le début du bloc alloué n’est pas défini par la norme C / C ++. Vous devez donc vous retrouver avec une solution non transférable. Vous devez suivre vous-même la longueur du bloc de mémoire.

L’exécution de cette application sur mon système (Ubuntu) indique:

 Length of str:1009 

Chaque bloc que vous allouez est précédé d’un descripteur de bloc. Le problème, c’est que cela dépend de l’architecture du système. Essayez de trouver la taille du descripteur de bloc pour votre propre système. Essayez de consulter la page de manuel de votre système malloc.