DOMANDA Cosa fa la funzione free in C

stex99.

Nuovo Utente
6
1
Volevo osservare come la funzione free operava sulle variabili.
per cui ho creato questo programmino molto semplice:
C:
#include <stdlib.h>
#include <stdio.h>

typedef struct node{
  struct node* next;} node;
typedef node* list;

list new(){
  list v;
  v=malloc(sizeof(node));
  v->next=NULL;}
int main(){
  list a,b;
  a=new();
  b=new();
  b->next=a;
  printf("%p -> %p\n",b,a);
  free(b);
  printf("%p -> %p\n",b,a);
  printf("b->next=%p\n",b->next);
  b->next=a;
  printf("%p -> %p",b,a);
  return 1;}
A quanto avevo capito, free riduce l'indirizzo b a come era prima del malloc, quindi quanto meno non modificabile da parte del programma.
Mi aspettavo l'errore "Segmentation fault", come il terminale spesso dice quando cerco di usare memoria non accessibile oppure non inizializzata.
Tuttavia questo è stato l'output:

0x56000f5b8280 -> 0x56000f5b8260
0x56000f5b8280 -> 0x56000f5b8260
b->next=(nil)
0x56000f5b8280 -> 0x56000f5b8260
Quindi su b sono riuscito sia a leggere che a sovrascrivere...
Ma allora mi chiedo a che serve la funzione free...
 

theprogrammer.99

Nuovo Utente
96
34
La free aggiorna le tabelle interne del sistema (del runtime) riguardanti le zone di memoria allocate nell'heap.
Non agisce affatto sulla memoria puntata, tanto meno sui puntatori.
Se le zone di memoria liberate dalla free sono ancora nello spazio degli indirizzi del processo, allora ci puoi scrivere (a tuo rischio, in quanto potrebbero essere riservate ad altri dati del processo alterando altri valori o lo stack). Se non fanno parte del dominio di indirizzi utilizzabili dal processo, allora interviene il kernel e hai un seg fault.
 
Ultima modifica:

DispatchCode

Moderatore
Staff Forum
Utente Èlite
2,223
1,854
CPU
Intel I9-10900KF 3.75GHz 10x 125W
Dissipatore
Gigabyte Aorus Waterforce X360 ARGB
Scheda Madre
Asus 1200 TUF Z590-Plus Gaming ATX DDR4
HDD
1TB NVMe PCI 3.0 x4, 1TB 7200rpm 64MB SATA3
RAM
DDR4 32GB 3600MHz CL18 ARGB
GPU
Nvidia RTX 3080 10GB DDR6
Audio
Integrata 7.1 HD audio
Monitor
LG 34GN850
PSU
Gigabyte P850PM
Case
Phanteks Enthoo Evolv X ARGB
Periferiche
MSI Vigor GK30, mouse Logitech
Net
FTTH Aruba, 1Gb (effettivi: ~950Mb / ~480Mb)
OS
Windows 10 64bit / OpenSUSE Tumbleweed
Concordo con quanto dice theprogrammer99.
Aggiungo solo alcune altre cose.

free() non cancella la memoria allocata. Quel chunk viene contrassegnato come riutilizzabile (e farà parte della lista dei "blocchi liberi", appunto).

Il fatto di non accedere ad una locazione che è stata liberata, sta a te programmatore: è noto come "dangling pointer" questa problematica, e consiste nell'avere due puntatori alla medesima locazione; richiami il free su uno, ma continui ad utilizzare l'altro (in alcuni linguaggi, come Rust ad esempio, questo non si verifica, grazie ad alcuni controlli).

Se scrivi su una locazione che hai già "liberato" (usando free()) non hai garanzia che quella locazione non sia già stata riservata/allocata a seguito di un'altra richiesta.
Da notare che se richiami ancora malloc() con la stessa dimensione è molto probabile che ti verrà anche riassegnato lo stesso indirizzo.
 
  • Mi piace
Reazioni: BAT e Mursey

theprogrammer.99

Nuovo Utente
96
34
Una ulteriore raccomandazione ... proprio per evitare problemi e individuare subito errori del genere, scrivi sempre

free(b);
b=NULL;

in modo che il riutilizzo del puntatore evidenzi un errore evitandoti mal di testa ...
 
  • Mi piace
Reazioni: Mursey

Ci sono discussioni simili a riguardo, dai un'occhiata!

Entra

oppure Accedi utilizzando
Discord Ufficiale Entra ora!

Discussioni Simili