Existe-t-il un moyen d'obtenir la taille de la mémoire allouée précédemment sur un tas?
Par exemple:Connaître la taille d'une mémoire réservée sur le tas
//pseudo-code
void* p = operator new (sizeof(int) * 3);
unsigned size = getSomeHow(p);
Existe-t-il un moyen d'obtenir la taille de la mémoire allouée précédemment sur un tas?
Par exemple:Connaître la taille d'une mémoire réservée sur le tas
//pseudo-code
void* p = operator new (sizeof(int) * 3);
unsigned size = getSomeHow(p);
Vous ne pouvez pas le faire en tout temps, car operator new()
peut être surchargée de quelque façon raisonnable et peut-être même sans utiliser le tas d'exécution.
Dans le cas où operator new()
est implémenté avec malloc()
dans Visual C++, vous pouvez utiliser _msize()
.
Bien que Sharptooth a raison dans sa réponse (nouveau peut être surchargé), la solution pourrait être juste dans ce fait. En surchargeant new, vous pouvez facilement ajouter votre propre implémentation de new et delete. Dans votre mise en œuvre d'une nouvelle, vous devez:
L'opérateur delete doit faire le contraire:
Si vous le faites de cette façon, assurez-vous d'implémenter toutes les saveurs de new et delete (lancer et non-lancer, nouveau et nouveau [], supprimer et supprimer [], ...).
Faites également attention aux bibliothèques tierces. Ils placent parfois l'appel à nouveau dans leur code compilé dans leur DLL, mais l'appel à supprimer dans l'en-tête. Cela signifie que new et delete utiliseront des implémentations différentes et que votre application va planter.
EDIT:
L'arrondi au multiple de 8 octets et l'ajout de 8 octets est nécessaire parce que les données doivent être stockées à un addres qui est un multiple de sa taille:
Depuis doubles sont le plus grand type de données natif que je suis au courant, nous arrondissons à un multiple de 8 octets et nous ajoutons 8 octets pour faire Assurez-vous de garder ces exigences.
Pourquoi exactement 8 octets et pas "assez d'octets pour stocker une variable' size_t' "? – sharptooth
Parce que les types de données natifs doivent être stockés sur une adresse qui est un multiple de sa taille. Normalement, le plus grand type de données est double, soit 8 octets. Par conséquent, nous devons ajouter 8 octets à la taille et au pointeur pour garder un multiple de 8 octets. (ajoutez une légère correction à mon article pour vous assurer que nous gardons ces multiples de 8 octets). – Patrick
D'accord, je vois. Alors ne devrait-il pas être 'max (sizeof (double), sizeof (void *))' ou quelque chose comme ça pour que le code soit portable sur les ordinateurs bit 1024 (ou peu importe)? – sharptooth
new
appeler malloc()
et stocker la taille dans une std::map<void*, size> alloc
mondiale.Ensuite, cette fonction getSomeHow()
se comportera comme vous voulez:
getSomeHow(void *p){
return alloc[p];
}
C'est génial, mais pourquoi ne pas simplement allouer un bloc un peu plus grand, écrire la taille allouée à son début et retourner un pointeur de décalage? – sharptooth
Hum oui, c'est beaucoup mieux en fait! – Ben
@Ben pourriez-vous s'il vous plaît fournir un indice sur la façon d'écrire mon propre malloc? Cela m'intéresse beaucoup. Merci d'avance –
Voulez-vous dire, précédemment alloué dans le code de votre fonction, le flux de contrôle de votre thread ou par votre processus, sur le tas, global? – einpoklum