Domanda

Dato un puntatore ad alcune variabili .. c'è un modo per verificare se è stato allocato staticamente o dinamicamente ??

È stato utile?

Soluzione

Citando dal tuo commento:

  

Sto realizzando un metodo che sostanzialmente eliminerà una struttura. ha un membro di dati che è un puntatore a qualcosa che può o non può essere maledetto .. a seconda di quale, vorrei liberarlo

Il modo corretto è aggiungere un altro membro alla struttura: un puntatore a una funzione di deallocazione.

Non è solo allocazione statica contro dinamica. Esistono diversi possibili allocatori, di cui malloc () è solo uno.

Su sistemi simili a Unix, potrebbe essere:

  • Una variabile statica
  • Sullo stack
  • Sullo stack ma allocato dinamicamente (ovvero alloca () )
  • Sull'heap, allocato con malloc()
  • Sull'heap, allocato con ne<
  • Sull'heap, nel mezzo di un array allocato con nuovo[[
  • Nell'heap, all'interno di una struttura allocata con malloc()
  • Sull'heap, all'interno di una classe base di un oggetto allocato con ne<
  • Assegnato con mmap
  • Allocato con un allocatore personalizzato
  • Molte altre opzioni, tra cui diverse combinazioni e varianti di quanto sopra

Su Windows, hai anche diversi runtime, LocalAlloc , GlobalAlloc , HeapAlloc (con diversi heap che puoi creare facilmente) e così via.

Devi sempre liberare memoria con la funzione di rilascio corretta per l'allocatore che hai usato. Quindi, o la parte del programma responsabile dell'allocazione della memoria dovrebbe liberare anche la memoria, oppure è necessario passare la funzione di rilascio corretta (o un wrapper al suo interno) al codice che libererà la memoria.

Puoi anche evitare l'intero problema richiedendo che il puntatore sia sempre allocato con un allocatore specifico o fornendo tu stesso l'allocatore (sotto forma di una funzione per allocare la memoria e possibilmente una funzione per rilasciarlo). Se fornisci tu stesso l'allocatore, puoi anche usare i trucchi (come i puntatori con tag) per consentire a uno di usare anche l'allocazione statica (ma non entrerò nei dettagli di questo approccio qui).

Raymond Chen ha un post sul blog (incentrato su Windows, ma i concetti sono lo stesso ovunque): Allocazione e liberazione della memoria oltre i confini del modulo

Altri suggerimenti

La ACE fa tutto questo. Potresti essere in grado di controllare come lo fanno. In generale probabilmente non dovresti aver bisogno di farlo in primo luogo però ...

Poiché l'heap, lo stack e l'area di dati statici occupano generalmente diversi intervalli di memoria, è possibile, con una conoscenza intima della mappa della memoria di processo, guardare l'indirizzo e determinare in quale area di allocazione si trova. Questa tecnica è specifico sia per l'architettura che per il compilatore, quindi rende più difficile il porting del codice.

La maggior parte delle implementazioni di libc malloc funzionano memorizzando un'intestazione prima di ogni blocco di memoria restituito che ha campi (che devono essere usati dalla chiamata free ()) che contiene informazioni sulla dimensione del blocco, oltre a un valore "magico". Questo valore magico serve a proteggere l'utente eliminando accidentalmente un puntatore che non è stato allocato (o liberando un blocco che è stato sovrascritto dall'utente). È molto specifico per il sistema, quindi dovresti guardare l'implementazione della tua libreria libc per vedere esattamente quale valore magico ci fosse.

Una volta che lo sai, sposta il puntatore dato indietro in modo da puntare all'intestazione e quindi controllalo per il valore magico.

Puoi agganciarti a malloc () stesso, come fanno i debugger di malloc, usando LD_PRELOAD o qualcosa del genere? In tal caso, è possibile mantenere una tabella di tutti i puntatori allocati e utilizzarlo. Altrimenti, non ne sono sicuro. C'è un modo per ottenere le informazioni contabili di malloc?

Non come funzionalità standard.
Una versione di debug della tua libreria malloc potrebbe avere qualche funzione per farlo.

Puoi confrontare il suo indirizzo con qualcosa che sai essere statico e dire che è maledetto solo se è lontano, se conosci l'ambito da cui dovrebbe provenire, ma se il suo ambito è sconosciuto, non puoi davvero fidarti che.

1.) Ottieni un file mappa per il codice che hai.

2.) La piattaforma di destinazione dell'hardware / del processo sottostante dovrebbe avere un file della mappa di memoria che in genere indica - l'indirizzo iniziale della memoria (stack, heap, global0, dimensione di quel blocco, attributi di lettura-scrittura di quel blocco di memoria.

3.) Dopo aver ottenuto l'indirizzo dell'oggetto (variabile puntatore) dal file mao in 1.) prova a vedere in quale blocco cade quell'indirizzo. potresti avere qualche idea.

= AD

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top