le mie informazioni di contatto
Posta[email protected]
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
1. Situazione di base
La gestione della memoria del linguaggio C è divisa in due parti: gestione del sistema e gestione del manuale utente del programmatore. La memoria gestita dal sistema è costituita principalmente dalle variabili (variabili locali) all'interno della funzione. Questa parte delle variabili entra nella memoria quando la funzione è in esecuzione. Questa parte dell'area di memoria diventa l'"area dello stack". , il sistema operativo lo scarica automaticamente dalla memoria. La memoria gestita manualmente dall'utente è costituita principalmente da variabili (variabili globali) che esistono durante l'intero processo di esecuzione del programma. L'area di memoria in cui si trova questa parte è chiamata "area heap". Queste variabili devono essere rilasciate manualmente dalla memoria dall'utente. Se ci si dimentica di rilasciarlo dopo l'uso, continuerà ad occupare memoria fino a quando non verrà consegnato al sistema operativo all'uscita del programma.
2. puntatore vuoto
Allo spazio di memoria nel computer viene assegnato un codice di indirizzo univoco e l'area di memoria specificata può essere trovata tramite il puntatore di memoria. Le variabili puntatore devono avere un tipo, ad esempio: int* p=&x; dichiara un puntatore di tipo int, che punta all'indirizzo della variabile intera x Quando il compilatore ottiene i dati da questo indirizzo, sa che il tipo int i dati sono memorizzati. Quando non si è sicuri del tipo di dati memorizzati e si desidera solo trovare prima l'indirizzo di memoria del blocco, viene utilizzato il puntatore del tipo void. Un puntatore di tipo void è anche chiamato puntatore di tipo indefinito e può puntare a qualsiasi tipo di dati.
I puntatori di tipo void possono essere convertiti in puntatori di altri tipi e non c'è nulla di speciale nel loro utilizzo, tranne che il contenuto memorizzato non può essere analizzato tramite il metodo "*".
int x = 10; //Dichiara la variabile intera x
void* p = &x; //Dichiara il puntatore void e punta all'indirizzo di x, indicando che il puntatore int (&x) viene convertito in un puntatore void.
int* q = p; // il puntatore void viene riconvertito in puntatore intero
printf("%in", *q); //Risultato dell'esecuzione: 10
Presta attenzione alla differenza tra void* e void: void è senza tipo e, quando viene utilizzato per dichiarare una funzione, significa che non viene restituito alcun valore, mentre void*, sebbene sia senza tipo ma abbia un puntatore, restituisce qualcosa;
3. Funzioni relative alla gestione della memoria
1、malloc()
Questa funzione può essere ricordata separatamente. m è l'abbreviazione di memoria e alloc è l'abbreviazione di allocazione. Insieme allocano la memoria.
Funzione: richiedere un blocco di memoria continua dall'area heap (promemoria: la memoria dell'area heap deve essere gestita dal programmatore e deve essere distrutta dopo l'uso. Questo dovrebbe essere sempre ricordato formato d'uso: malloc (fare riferimento a 1);
Parametri: il parametro 1 è la dimensione del blocco di memoria (un numero intero non negativo di tipo size_t, il valore restituito di sizeof è di questo tipo)
Valore restituito: void* puntatore (useremo qualunque tipo di puntatore utilizziamo per ricevere la memoria allocata)
Utilizzo: le variabili dichiarate utilizzando la funzione malloc si trovano nell'area heap, quindi viene spesso utilizzato il metodo di dichiarazione anonima, ovvero invece di utilizzare il metodo di indirizzo di variabili specifiche, malloc restituisce direttamente il puntatore, come mostrato di seguito:
int* ptr = (int*) malloc(sizeof(int)); //Una variabile puntatore int viene dichiarata nell'area heap
La conversione forzata tra parentesi non è necessaria. malloc restituisce void*, che può essere ricevuto con int*. La conversione forte qui rende il codice più facile da comprendere.
Precauzioni:
a. Utilizzare la funzione malloc per includere<stdlib.h>file di intestazione, come contiene solo<stdio.h> Si compila bene ma non funziona correttamente, tienilo a mente.
b. Assegnare un valore a ptr: *ptr=1000;.
c. Utilizzare malloc insieme a free (che incontrerai più avanti).
d. Malloc potrebbe non riuscire ad allocare gli indirizzi. Se non riesce, restituirà NULL. Per questo motivo, è possibile aggiungere un'istruzione if per l'elaborazione.
e. malloc alloca solo memoria, indipendentemente dall'inizializzazione. Se è richiesta l'inizializzazione, è necessario chiamare un'altra funzione.
f. L'occasione più comunemente utilizzata per malloc è allocare memoria per array e strutture dati personalizzate.
2、 memset()
Funzione: Assegna ad ogni byte del blocco di memoria puntato da un puntatore un valore iniziale.
Parametri: Parametro 1 Puntatore che punta alla memoria di destinazione Parametro 2 Contenuto dell'assegnazione (valore del codice ASCII di tipo int o carattere di tipo char) Parametro 3 Numero di byte da assegnare (tipo size_t)
Valore di ritorno: Restituisce il puntatore puntato alla memoria di destinazione Non ha senso ricevere, lo stesso del parametro 1.
Utilizzo: memset(ptrDestMem,'A',sizeof(char)*1024) //Assegna il carattere A a ciascun byte di un blocco di memoria con una lunghezza di 1024 byte
Precauzioni:
a. Il file di intestazione a cui appartiene questa funzione è<string.h> , alcuni compilatori possono essere utilizzati normalmente senza includere questo file di intestazione. Se si verifica un errore di esecuzione, includerlo.
b. Si noti che memset è un'operazione sui byte (non sui bit); il parametro 3 si riferisce al numero di byte che devono essere assegnati, che può essere inferiore o uguale al numero di byte nella memoria di destinazione, ma non può superare il limite.
c. Il valore del parametro 2 non può superare quanto può essere contenuto in un byte (tipo int 255). Se supera il valore, non può essere scritto.
2、gratuito()
Funzione: funzione abbinata a malloc, utilizzata per rilasciare la memoria allocata dalla funzione malloc e prevenire perdite di memoria
Parametri: puntatore restituito dalla funzione malloc
Utilizzo: gratuito (ptr);
Precauzioni:
a. Anche i file header che devono essere inclusi quando si utilizza free<stdlib.h> , non dimenticare.
b. La funzione libera può essere eseguita solo una volta e lo stesso indirizzo di memoria non può essere rilasciato ripetutamente e il puntatore rilasciato non può essere utilizzato nuovamente.
c. È meglio scrivere prima malloc e free in coppia, quindi inserire altri codici al centro per evitare di dimenticarli.
3、realloc()
re, che significa ancora una volta, abbreviazione di allocazione alloc, insieme significa riallocazione della memoria
Funzione: Modifica la dimensione del blocco di memoria allocato (aumento o diminuzione).
Parametri: parametro 1, puntatore del blocco di memoria originale, parametro 2, dimensione del blocco di memoria dopo l'aumento o la diminuzione (ancora tipo size_t)
Valore restituito: puntatore void* (può essere ricevuto dalla variabile di tipo puntatore originale)
Utilizzo: void* newPtr=realloc(ptr,sizeof(int)*10);
Precauzioni:
a. Quando si utilizza la funzione realloc, è necessario includerla anche<stdlib.h> .
b. Il blocco di memoria a cui punta il puntatore originale è stato sostituito dal nuovo puntatore, quindi è il nuovo puntatore che dovrebbe essere liberato al termine del programma e non è necessario liberare il puntatore originale, altrimenti si verificherà un errore di operazione. verificarsi.
c. realloc potrebbe non riuscire ad allocare memoria e restituire NULL se fallisce, quindi è meglio aggiungere un'istruzione if per gestire il problema.
4. Esempi di applicazione
- #include<stdio.h>
- #include<stdlib.h> //malloc、free、realloc
- #include<string.h> //memset
- int main(void)
- {
- //A void指针的使用
- float PI = 3.14159;
- void* pPI = &PI;
- float r = 2.5;
- printf("半径2.5圆的面积:%fn", r * r * *(float*)pPI);//*(float*)pPI—pPI强转为float指针后再解出指向的值
- //B malloc、memset、free函数使用
- int n = 8;
- void* pMyMem = malloc(sizeof(char)*n); //char占1字节,malloc分派n字节的内存,返给void指针
- if (pMyMem == NULL)return 0; //若分派内存失败,程序结束
- void* myMem2=memset(pMyMem,'B',sizeof(char)*8); //对malloc分派的内存区块个字节都写入字符'B'。
- //并用myMem2接收返回的指针
- if (pMyMem == myMem2)printf("memset写入区块指针与其返回的指针相同n");
- char* transCh = pMyMem; //将void指针转成char型指针
- printf("显示写入内容:");
- for (int i = 0; i < n; i++)
- {
- printf("%c ", *transCh); //显示写入的字符
- transCh++;
- }
- printf("n");//换行
- free(pMyMem); //释放malloc函数分派的内存
- //free(ch); //只有malloc分派的内存才需要释放,且只释放一次(这里会报错)
- //C realloc、free函数的使用
- int* pMem = malloc(sizeof(int)*5);
- if (pMem == NULL)return 0;
- for (int i = 0; i < 5; i++) pMem[i] = (i+1)*10;
- for (int i = 0; i < 5; i++) printf("%i ", pMem[i]);
- printf("n重新增加分派内存后n");
- int* newpMem = realloc(pMem, sizeof(int) * 10);
- if (newpMem == NULL)return 0;
- for (int i = 0; i < 10; i++) newpMem[i] = (i + 1) * 10;
- for (int i = 0; i < 10; i++)printf("%i ", newpMem[i]);
- free(newpMem); //释放realloc的内存
- //free(pMem);//pMem已被重置,不能再释放,此语句会造成运行失败
- getchar(); //暂停屏幕
- return 0;
- }