国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

C語言->動態(tài)內存管理

這篇具有很好參考價值的文章主要介紹了C語言->動態(tài)內存管理。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

系列文章目錄


文章目錄


前言

C語言->動態(tài)內存管理,C語言,c語言,開發(fā)語言,學習

??作者簡介:大家好,我是橘橙黃又青,一個想要與大家共同進步的男人????

??個人主頁:橘橙黃又青_C語言,函數(shù),指針-CSDN博客

目的:學習malloc,free,calloc,realloc函數(shù)的使用。

內存函數(shù)在#include<stdio.h>頭文件里面。

1. 為什么要有動態(tài)內存分配

我們已經(jīng)掌握的內存開辟?式有:

int val = 20;//在??臻g上開辟四個字節(jié)
char arr[10] = {0};//在??臻g上開辟10個字節(jié)的連續(xù)空間
但是上述的開辟空間的?式有兩個特點:
? 空間開辟??是固定的。
? 數(shù)組在申明的時候,必須指定數(shù)組的?度,數(shù)組空間?旦確定了??不能調整。
但是對于空間的需求,不僅僅是上述的情況。有時候我們需要的空間??在程序運?的時候才能知
道,那數(shù)組的編譯時開辟空間的?式就不能滿?了。
C語?引?了動態(tài)內存開辟,讓程序員??可以申請和釋放空間,就?較靈活了。
補充一下動態(tài)內存在內存中的分布:
C語言->動態(tài)內存管理,C語言,c語言,開發(fā)語言,學習

2. malloc和free

2.1 malloc

C語?提供了?個動態(tài)內存開辟的函數(shù):

void* malloc (size_t size);

這個函數(shù)向內存申請?塊連續(xù)可?的空間,并返回指向這塊空間的指針。 ?

? 如果開辟成功,則返回?個指向開辟好空間的指針。
? 如果開辟失敗,則返回?個 NULL 指針,因此malloc的返回值?定要做檢查。
? 返回值的類型是 void* ,所以malloc函數(shù)并不知道開辟空間的類型,具體在使?的時候使?者? ?來決定。
? 如果參數(shù) size 為0,malloc的?為是標準是未定義的,取決于編譯器

代碼演示:

int* p = (int*)malloc(10 * sizeof(int))開辟10個整形空間
malloc(字節(jié))

2.2 free

C語?提供了另外?個函數(shù)free,專?是?來做動態(tài)內存的釋放和回收的,函數(shù)原型如下:
void free (void* ptr);
free函數(shù)?來釋放動態(tài)開辟的內存注意:
? 如果參數(shù) ptr 指向的空間不是動態(tài)開辟的,那free函數(shù)的?為是未定義的。
? 如果參數(shù) ptr 是NULL指針,則函數(shù)什么事都不做。
malloc和free都聲明在 stdlib.h 頭?件中。

舉個例?:

#include <stdio.h>
#include <stdlib.h>
int main()
{
     int num = 0;
     scanf("%d", &num);
     int arr[num] = {0};
     int* ptr = NULL;
     ptr = (int*)malloc(num*sizeof(int));
     if(NULL != ptr)//判斷ptr指針是否為空
     {
         int i = 0;
         for(i=0; i<num; i++){
             *(ptr+i) = 0;
         }
     }
     free(ptr);//釋放ptr所指向的動態(tài)內存
     ptr = NULL;
     return 0;
}

3. calloc和realloc

3.1 calloc

C語?還提供了?個函數(shù)叫 calloc , calloc 函數(shù)也?來動態(tài)內存分配。原型如下:
void* calloc (size_t num, size_t size);
? 函數(shù)的功能是為 num 個??為 size 的元素開辟?塊空間,并且把空間的每個字節(jié)初始化為0。
? 與函數(shù) malloc 的區(qū)別只在于 calloc 會在返回地址之前把申請的空間的每個字節(jié)初始化為全
0 。
舉個例?:
#include <stdio.h>
#include <stdlib.h>
int main()
{
     int *p = (int*)calloc(10, sizeof(int));
     if(NULL != p)
     {
         int i = 0;
         for(i=0; i<10; i++){
             printf("%d ", *(p+i));
         }
     }
     free(p);
     p = NULL;
     return 0;
}

輸出結果:

C語言->動態(tài)內存管理,C語言,c語言,開發(fā)語言,學習

所以如果我們對申請的內存空間的內容要求初始化,那么可以很?便的使?calloc函數(shù)來完成任務。

3.2 realloc

? realloc函數(shù)的出現(xiàn)讓動態(tài)內存管理更加靈活。
? 有時會我們發(fā)現(xiàn)過去申請的空間太?了,有時候我們?會覺得申請的空間過?了,那為了合理的時
候內存,我們?定會對內存的??做靈活的調整。那 realloc 函數(shù)就可以做到對動態(tài)開辟內存??的調整。

函數(shù)原型如下:

void* realloc (void* ptr, size_t size);
? ptr 是要調整的內存地址
? size 調整之后新??
? 返回值為調整之后的內存起始位置。
? 這個函數(shù)調整原內存空間??的基礎上,還會將原來內存中的數(shù)據(jù)移動到 新 的空間。
realloc在調整內存空間的是存在兩種情況:
????????情況1:原有空間之后有?夠?的空間
????????情況2:原有空間之后沒有?夠?的空間

C語言->動態(tài)內存管理,C語言,c語言,開發(fā)語言,學習

情況1:
當是情況1 的時候,要擴展內存就直接原有內存之后直接追加空間,原來空間的數(shù)據(jù)不發(fā)?變化。
情況2:
當是情況2 的時候,原有空間之后沒有?夠多的空間時,擴展的?法是:在堆空間上另找?個合適?? 的連續(xù)空間來使?。這樣函數(shù)返回的是?個新的內存地址。
由于上述的兩種情況,realloc函數(shù)的使?就要注意?些。
#include <stdio.h>
#include <stdlib.h>
int main()
{
     int *ptr = (int*)malloc(100);
     if(ptr != NULL)
     {
         //業(yè)務處理
     }
     else
     {
         return 1; 
     }
     //擴展容量
 
     //代碼1 - 直接將realloc的返回值放到ptr中
     ptr = (int*)realloc(ptr, 1000);//這樣可以嗎?(如果申請失敗會如何?)
 
     //代碼2 - 先將realloc函數(shù)的返回值放在p中,不為NULL,在放ptr中
     int*p = NULL;
     p = realloc(ptr, 1000);
     if(p != NULL)//判斷
     {
         ptr = p;
     }
     //業(yè)務處理
     free(ptr);
     return 0;
}

4. 常?的動態(tài)內存的錯誤

4.1 對NULL指針的解引?操作

void test()
 {
     int *p = (int *)malloc(INT_MAX/4);
     *p = 20;//如果p的值是NULL,就會有問題
     free(p);
 }

所以使用動態(tài)內存函數(shù)是一定要養(yǎng)成習慣判斷是否為NULL

4.2 對動態(tài)開辟空間的越界訪問

void test()
 {
     int i = 0;
     int *p = (int *)malloc(10*sizeof(int));
     if(NULL == p)
     {
         exit(EXIT_FAILURE);//報錯
     }
     for(i=0; i<=10; i++)//問題就出在i==10
     {
         *(p+i) = i;//當i是10的時候越界訪問
     }
     free(p);
 }

4.3 對?動態(tài)開辟內存使?free釋放

void test()
 {
     int a = 10;
     int *p = &a;
     free(p);//ok?
 }

4.4 使?free釋放?塊動態(tài)開辟內存的?部分

void test()
 {
     int *p = (int *)malloc(100);
     p++;
     free(p);//p不再指向動態(tài)內存的起始位置
 }

4.5 對同?塊動態(tài)內存多次釋放

void test()
 {
     int *p = (int *)malloc(100);
     free(p);
     free(p);//重復釋放
 }

4.6 動態(tài)開辟內存忘記釋放(內存泄漏)

void test()
 {
     int *p = (int *)malloc(100);
     if(NULL != p)
     {
         *p = 20;
     }
 }
int main()
 {
     test();
     while(1);
 }
忘記釋放不再使?的動態(tài)開辟的空間會造成內存泄漏。
切記:動態(tài)開辟的空間?定要釋放,并且正確釋放 。

5. 動態(tài)內存經(jīng)典筆試題分析

5.1 題?1:

void GetMemory(char *p)
 {
     p = (char *)malloc(100);
 }
void Test(void)
 {
     char *str = NULL;
     GetMemory(str);
     strcpy(str, "hello world");
     printf(str);
 }

輸出結果是什么?

C語言->動態(tài)內存管理,C語言,c語言,開發(fā)語言,學習

為什么?

這是因為str 傳過去char*p是相當于值傳遞,是臨時拷貝的str,函數(shù)銷毀后,str還是不變,str還是NULL,所以沒有輸出。

5.2 題?2:

char *GetMemory(void)
 {
     char p[] = "hello world";
     return p;
 }
void Test(void)
 {
     char *str = NULL;
     str = GetMemory();
     printf(str);
 }

輸出結果:

C語言->動態(tài)內存管理,C語言,c語言,開發(fā)語言,學習

因為:

在這里p的地址的確傳了回去的是地址后面的空間銷毀了,所以才會出現(xiàn)這結果。

5.3 題?3:

void GetMemory(char **p, int num)
 {
     *p = (char *)malloc(num);
 }
void Test(void)
 {
     char *str = NULL;
     GetMemory(&str, 100);
     strcpy(str, "hello");
     printf(str);

//   free(str);
//   str = NULL;
 }

忘記了釋放

5.4 題?4:

void Test(void)
 {
     char *str = (char *) malloc(100);
     strcpy(str, "hello");
     free(str);
     if(str != NULL)
     {
         strcpy(str, "world");
         printf(str);
     }
 }

忘記str = NULL,且釋放空間后又把world放進去,//非法訪問

6. 柔性數(shù)組

也許你從來沒有聽說過柔性數(shù)組(flexible array)這個概念,但是它確實是存在的。
C99 中,結構中的最后?個元素允許是未知??的數(shù)組,這就叫做『柔性數(shù)組』成員。
例如:
typedef struct st_type
{
     int i;
     int a[0];//柔性數(shù)組成員
}type_a;
有些編譯器會報錯?法編譯可以改成:
typedef struct st_type
{
     int i;
     int a[];//柔性數(shù)組成員
}type_a;

6.1 柔性數(shù)組的特點: ?

? 結構中的柔性數(shù)組成員前?必須?少?個其他成員 。
? sizeof 返回的這種結構??不包括柔性數(shù)組的內存 。
? 包含柔性數(shù)組成員的結構?malloc ()函數(shù)進?內存的動態(tài)分配,并且分配的內存應該?于結構的??,以適應柔性數(shù)組的預期??。

例如:?

typedef struct st_type
{
     int i;
     int a[0];//柔性數(shù)組成員
}type_a;
int main()
{
     printf("%d\n", sizeof(type_a));//輸出的是4
     return 0;
}

6.2 柔性數(shù)組的使?

代碼1:

#include <stdio.h>
#include <stdlib.h>
struct St
{
	char c;
	int n;
	int arr[0];
};
int main()
{
	struct St* ps = (struct St*)malloc(sizeof(struct St) + 10 * sizeof(int));//柔性數(shù)組開辟的空間:10 * sizeof(int)
	if (ps == NULL)
	{
		perror("malloc");
		return 1;
	}
	ps->c = 'w';
	ps->n = 100;
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		ps->arr[i] = i;
	}
	//數(shù)組空間不夠
	struct St* ptr = realloc(ps, sizeof(struct St) + 15 * sizeof(int));//改變柔性數(shù)組空間
	if (ptr != NULL)
	{
		ps = ptr;
	}
	else
	{
		perror("realloc");//報錯
		return 1;
	}
	//...繼續(xù)使用

	for (i = 10; i < 15; i++)
	{
		ps->arr[i] = i;
	}

	for (i = 0; i < 15; i++)
	{
		printf("%d ", ps->arr[i]);
	}
	printf("\n%d\n", ps->n);
	printf("%c\n", ps->c);

	//釋放
	free(ps);
	ps = NULL;

	return 0;
}

還有另一種方式:

代碼2:

struct St
{
	char c;
	int n;
	int* arr;//使用指針的方式訪問
};


int main()
{
	struct St* ps = (struct St*)malloc(sizeof(struct St));
	if (ps == NULL)
	{
		perror("malloc");//報錯
		return 1;
	}
	ps->c = 'w';
	ps->n = 100;

	ps->arr = (int*)malloc(10 * sizeof(int));//給柔性數(shù)組開辟空間
	if (ps->arr == NULL)//判斷
	{
		perror("malloc-2");//報錯
		return 1;
	}
	//使用
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		ps->arr[i] = i;
	}

	//數(shù)組空間不夠
	int* ptr = (int*)realloc(ps->arr, 15 * sizeof(int));//這個可以,重點
	if (ptr == NULL)
	{
		perror("realloc");
		return 1;
	}
	else
	{
		ps->arr = ptr;
	}
	//使用
	for (i = 10; i < 15; i++)
	{
		ps->arr[i] = i;
	}
	for (i = 0; i < 15; i++)
	{
		printf("%d ", ps->arr[i]);
	}
	printf("\n%d\n", ps->n);
	printf("%c\n", ps->c);

	//釋放兩次
	free(ps->arr);
	ps->arr = NULL;

	free(ps);
	ps = NULL;

	return 0;
}

上述的 type_a 結構也可以設計為下?的結構,也能完成同樣的效果:

//代碼2
#include <stdio.h>
#include <stdlib.h>
typedef struct st_type
{
     int i;
     int *p_a;
}type_a;
int main()
{
     type_a *p = (type_a *)malloc(sizeof(type_a));
     p->i = 100;
     p->p_a = (int *)malloc(p->i*sizeof(int));
 
     //業(yè)務處理
     for(i=0; i<100; i++)
     {
         p->p_a[i] = i;
     }
 
     //釋放空間
     free(p->p_a);
     p->p_a = NULL;
     free(p);
     p = NULL;
     return 0;
}

這樣就簡化很多了。

6.3 柔性數(shù)組的優(yōu)勢

上述 代碼1 和 代碼2 可以完成同樣的功能,但是 ?法1 的實現(xiàn)有兩個好處:文章來源地址http://www.zghlxwxcb.cn/news/detail-760994.html

第?個好處是:?便內存釋放
如果我們的代碼是在?個給別??的函數(shù)中,你在??做了?次內存分配,并把整個結構體返回給? ?。??調?free可以釋放結構體,但是??并不知道這個結構體內的成員也需要free,所以你不能指望??來發(fā)現(xiàn)這個事。所以,如果我們把結構體的內存以及其成員要的內存?次性分配好了,并返回給???個結構體指針,??做?次free就可以把所有的內存也給釋放掉。
第?個好處是:這樣有利于訪問速度.
連續(xù)的內存有益于提?訪問速度,也有益于減少內存碎?。(其實,我個?覺得也沒多?了,反正你 跑不了要?做偏移量的加法來尋址)。
擴展閱讀:
C語?結構體?的數(shù)組和指針。
好了今天就到這里了,都看到這里了點一個贊吧,感謝觀看。

到了這里,關于C語言->動態(tài)內存管理的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉載,請注明出處: 如若內容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • 動態(tài)內存管理(C語言)

    動態(tài)內存管理(C語言)

    我們已經(jīng)掌握的內存開辟方式有 int val = 20;//在??臻g上開辟四個字節(jié) char arr[10] = {0};//在??臻g上開辟10個字節(jié)的連續(xù)空間 但上述開辟內存的方式有兩個特點 空間開辟大小是固定的 數(shù)組在聲明時必須指定數(shù)組的長度,他所需要的內存在編譯時分配 但是對于空間的需求,不僅

    2024年02月16日
    瀏覽(25)
  • 動態(tài)內存管理-c語言

    動態(tài)內存管理-c語言

    目錄 1.為什么要有動態(tài)內存分配 2.malloc函數(shù)和free函數(shù) malloc 函數(shù)原型 栗子 free 函數(shù)原型 栗子 3.calloc和***realloc*** 3.1calloc函數(shù) 原型如下: 栗子 3.2***recalloc*** 第一種情況 第二種情況 第三種情況 recalloc模擬實現(xiàn)calloc函數(shù) 4.六大常?的動態(tài)內存的錯誤 4.1對NULL指針的解引?操作

    2024年03月22日
    瀏覽(28)
  • C語言->動態(tài)內存管理

    C語言->動態(tài)內存管理

    文章目錄 ??作者簡介:大家好,我是橘橙黃又青,一個想要與大家共同進步的男人???? ??個人主頁:橘橙黃又青_C語言,函數(shù),指針-CSDN博客 目的:學習malloc,free,calloc,realloc函數(shù)的使用。 內存函數(shù)在#includestdio.h頭文件里面。 我們已經(jīng)掌握的內存開辟?式有: 但是上述的

    2024年02月04日
    瀏覽(21)
  • c語言-動態(tài)內存管理

    c語言-動態(tài)內存管理

    1.我們一般的開辟空間方式: 2.這樣開辟空間的特點 (1)申請的空間大小是固定的 (2)像數(shù)組那樣一開始就要確定大小,一旦確定大小就不能改變了 3.動態(tài)內存 對于程序來說上述的內存申請是不能滿足 因此為了能夠對內存進行調整,C語言引入了動態(tài)內存開辟,讓程序員自

    2024年02月04日
    瀏覽(27)
  • C語言:動態(tài)內存管理

    C語言:動態(tài)內存管理

    先點贊再觀看哦! 學習數(shù)據(jù)結構之前,一定要對指針、結構體、動態(tài)內存管理進行深入學習! 小伙伴們可以看看博主之前的文章! 今天重點介紹動態(tài)內存開辟!十分重要哈! 我們已知的內存開辟方式有什么呢?? 但是上述開辟的空間有三個特點: 1、空間開辟的大小是固定

    2024年01月22日
    瀏覽(31)
  • <C語言> 動態(tài)內存管理

    <C語言> 動態(tài)內存管理

    為什么存在動態(tài)內存分配? 上述的開辟空間的方式有兩個特點: 空間開辟大小是固定的。 數(shù)組在聲明的時候,必須指定數(shù)組的長度,它所需要的內存在編譯時分配。 但是對于空間的需求,不僅僅是上述的情況。有時候我們需要的空間大小在程序運行的時候才能知道,那數(shù)組

    2024年02月15日
    瀏覽(24)
  • 【C語言:動態(tài)內存管理】

    【C語言:動態(tài)內存管理】

    文章的標題是動態(tài)內存管理,那什么是動態(tài)內存管理?為什么有動態(tài)內存管理呢? 回顧一下以前學的知識,我們已經(jīng)掌握的開辟內存的方式有以下幾種: 上述開辟內存的方式有幾個弊端: 開辟空間的大小是固定的 數(shù)組在聲明的時候,必須指定數(shù)組的長度,數(shù)組空間?旦確定

    2024年02月03日
    瀏覽(25)
  • 【C語言】動態(tài)內存管理

    【C語言】動態(tài)內存管理

    大家好,我是蘇貝,本篇博客帶大家了解動態(tài)內存管理,如果你覺得我寫的還不錯的話,可以給我一個贊??嗎,感謝?? 我們已經(jīng)掌握的內存開辟方式有: int val = 20; 在棧空間上開辟四個字節(jié) char arr[10] = {0}; 在??臻g上開辟10個字節(jié)的連續(xù)空間 但是上述的開辟空間的方式有

    2024年01月16日
    瀏覽(30)
  • 【C語言】動態(tài)內存的管理

    【C語言】動態(tài)內存的管理

    前言 本篇博客就來探討一下動態(tài)內存,說到內存,我們以前開辟空間大小都是固定的,不能調整這個空間大小,于是就有動態(tài)內存,可以讓我們自己選擇開辟多少空間,更加方便,讓我們一起來看看動態(tài)內存的有關知識吧 個人主頁:小張同學zkf 若有問題 評論區(qū)見 感興趣就

    2024年04月15日
    瀏覽(12)
  • 進階C語言-動態(tài)內存管理

    進階C語言-動態(tài)內存管理

    ?截止目前,我們掌握的內存開辟的方式有: 但是上述的開辟空間的方式有兩個特點: 空間開辟的大小是固定的。 數(shù)組在申明的時候,必須指定數(shù)組的長度,它所需的內存在編譯時分配。 ??但是對于空間的需求,不僅僅是上述的情況。有時候我們需要的空間大小在程序運

    2024年02月21日
    瀏覽(26)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包