最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C語言動態(tài)內(nèi)存分配和內(nèi)存操作函數(shù)使用詳解

 更新時間:2022年12月27日 08:43:59   作者:編程遠(yuǎn)泊  
但是在實(shí)際的編程中,往往會發(fā)生這種情況,即所需的內(nèi)存空間取決于實(shí)際輸入的數(shù)據(jù),而無法預(yù)先確定 。為了解決上述問題,C語言提供了一些內(nèi)存管理函數(shù),這些內(nèi)存管理函數(shù)可以按需要動態(tài)的分配內(nèi)存空間,也可把不再使用的空間回收再次利用

1 動態(tài)內(nèi)存分配的介紹

  • 手動分配空間手動釋放空間,根據(jù)自己的需要分配固定大小的內(nèi)存空間。
  • 動態(tài)內(nèi)存分配在堆區(qū)分配的空間,堆區(qū)空間需要手動分配,手動釋放。
  • 分配堆區(qū)的函數(shù)使用malloc函數(shù),釋放堆區(qū)空間使用free函數(shù)。
  • 如果堆區(qū)空間沒有手動釋放,當(dāng)進(jìn)程結(jié)束,系統(tǒng)會回收堆區(qū)的空間,一般都是手動釋放

2 malloc和free函數(shù)

#include <stdlib.h>

malloc函數(shù) ----> 在堆區(qū)分配空間
void *malloc(size_t size);
功能:手動在堆區(qū)分配內(nèi)存空間
參數(shù):
@ size : 分配堆區(qū)空間的大小,以字節(jié)為單位
返回值:
成功:返回分配堆區(qū)空間的首地址
失敗:返回NULL

free函數(shù) ----> 釋放堆區(qū)的空間
void free(void *ptr);
功能:手動釋放堆區(qū)的空間
參數(shù):
@ ptr : 釋放堆區(qū)空間的首地址
返回值:無

3 測試代碼

#include <stdio.h>
#include <stdlib.h>
int main(int argc, const char *argv[])
{
    /*your code*/
#if   0
    // 回顧:定義指針變量的初始化方式
    int *p = NULL;   // 指針變量p在棧區(qū)分配的空間
    int a = 100;     // 變量a在棧區(qū)分配的空間
    p = &a;   // 指針p指向棧區(qū)空間
    char *str = "hello world"; 
            // 指針變量str在棧區(qū)分配的空間
            // "hello world" 在字符串的常量區(qū)
#endif 
    // 定義一個指針變量,指向一個堆區(qū)的空間 
    int *m_p = NULL;
    m_p = (int *)malloc(sizeof(int));
    // 對返回值進(jìn)行判斷
    if(m_p == NULL) {
        printf("malloc memory failed!\n");
        return -1;
    }
    printf("malloc memory successed!\n");
    // 對m_p指針指向的堆區(qū)空間進(jìn)行初始化
    *m_p = 1000;
    printf("打印堆區(qū)空間中的值 : %d\n", *m_p);
#if 0
    // 釋放堆區(qū)的空間
    free(m_p);
    // 將m_p指向NULL,防止野指針的出現(xiàn)
    m_p = NULL;
#endif 
    // 為什么必須釋放完堆區(qū)空間指針讓指針指向NULL,如果不指向有可能會出現(xiàn)野指針
    printf("釋放之前,m_p指針變量中存放的地址 = %p\n", m_p);
    // 釋放堆區(qū)的空間, 
    // free函數(shù)只是單純的釋放了堆區(qū)的空間,別人就可以再次使用這塊堆區(qū)空間,
    // free函數(shù)并沒有將m_p指針變量中存放的地址清空,因此需要成需要手動將m_p指向NULL
    free(m_p);
    printf("釋放之后,m_p指針變量中存放的地址 = %p\n", m_p);
    // 釋放堆區(qū)空間沒有將m_p指向NULL,此時依然可以對m_p指向的空間賦值,
    // 并且編譯不會報錯,也可以正常指向,但是這樣就訪問了非法的空間。
    *m_p = 2000;
    printf("打印釋放堆區(qū)空間之后m_p指向的空間的值 : %d\n", *m_p);
    // 如果將m_p指向null之后,就可以預(yù)防野指針的出現(xiàn),
    // 當(dāng)執(zhí)行程序時就會報段錯誤
    m_p = NULL;
    *m_p = 3000;
    printf("打印釋放堆區(qū)空間之后m_p指向的空間的值 : %d\n", *m_p);//段錯誤
    return 0;
}

練習(xí)題:使用malloc在堆區(qū)給int *p; 分配(sizeof(int) * 10),大小的空間,通過終端輸入的方式對堆區(qū)進(jìn)行初始化,然后使用冒泡排序的方式對堆區(qū)空間中的成員進(jìn)行排序。使用多文件編程的方式實(shí)現(xiàn)。

bubbling.h文件:

#ifndef __BUBBLING_H__
#define __BUBBLING_H__
#include <stdio.h>
#include <stdlib.h>
int *malloc_int(int len);
void print(int *p,int len);
void bubbling(int *p,int len);
void free_p(int *p);
#endif

main.c文件:

#include "bubbling.h"
int main(int argc, const char *argv[])
{
    printf("請輸入要輸入元素的個數(shù)>");
    int n=0;
    scanf("%d",&n);
    int *p=malloc_int(n);
    printf("請輸入要排序的元素>\n");
    for(int i=0;i<n;i++){
        scanf("%d",p+i);
    }
    printf("未排序前>\n");
    print(p,n);
    bubbling(p,n);
    printf("排序后>\n");
    print(p,n);
    free_p(p);
    p=NULL;
    return 0;
}

malloc_free.c文件:

#include "bubbling.h"
int *malloc_int(int len){
    int *q=(int *)malloc(sizeof(int)*len);
    if(NULL==q){
        printf("申請空間失敗!\n");
    }
    return q;
}
void free_p(int *p){
    if(NULL==p){
        printf("傳參錯誤!\n");
    }
    free(p);
    p=NULL;
}

bubbling.c文件:

#include "bubbling.h"
void bubbling(int *p,int len){
    if(NULL==p){
        printf("傳參錯誤!\n");
    }
    for(int j = 0; j < len-1; j++){
		//內(nèi)層循環(huán)控制一趟排序
		for(int i = 0; i < len-1-j; i++){
					//此處的 -1 是防止越界訪問的
					//此處的 -j 是因?yàn)槊刻硕伎梢陨俦容^一個元素
			if(p[i] > p[i+1]){//如果是降序 只需要將此處的 > 改成 < 即可
				//交換
				int temp = p[i];
				p[i] = p[i+1];
				p[i+1] = temp;
			}
		}
	}
}

print.c文件:

#include "bubbling.h"
void print(int *p,int len){
    if(NULL==p){
        printf("傳參錯誤!\n");
    }
    for(int i=0;i<len;i++){
        printf("%4d",*(p+i));
    }
    puts("");
}

4 goto的使用場合

常用于出錯處理

#include <stdio.h>
#include <stdlib.h>
int main(int argc, const char *argv[])
{
    /*your code*/
    // 1. 定義3個指針類型的變量,最終都指向一個堆區(qū)的空間
    int *i_p = NULL;
    short *s_p = NULL;
    char *c_p = NULL;
    i_p = (int *)malloc(sizeof(int));
    if ( i_p == NULL) 
    {
        printf("i_p malloc memory failed!\n");
        // 如果失敗直接退出,沒有問題
        goto ERR1;
    }
    s_p = (short *)malloc(sizeof(short));
    if ( s_p == NULL) 
    {
        printf("s_p malloc memory failed!\n");
        // 如果失敗需要先將i_p指向的堆區(qū)空間釋放     
        goto ERR2;
    }
    c_p = (char *)malloc(sizeof(char));
    if ( c_p == NULL) 
    {
        printf("c_p malloc memory failed!\n");
        // 如果失敗需要先將i_p和s_p指向的堆區(qū)空間釋放
        goto ERR3;
    }
    // 如果都分配成功,不使用時手動釋放,
    // 如果不手動釋放,當(dāng)進(jìn)行結(jié)束之后,系統(tǒng)也會進(jìn)行回收。
    free(c_p);
    free(s_p);
    free(i_p);
    return 0;
ERR3:
    free(s_p);
ERR2:
    free(i_p);
ERR1:
    return -1;
}

宏定義函數(shù)版:

#include <stdio.h>
#include <stdlib.h>
#define NODE(T) T *T##_p = NULL;
#define MALLOC(T) T##_p=(T *)malloc(sizeof(T)); 
int main(int argc, const char *argv[])
{
    /*your code*/
    // 1. 定義3個指針類型的變量,最終都指向一個堆區(qū)的空間
    // int *int_p = NULL;
    NODE(int)
    // short *s_p = NULL;
    NODE(short)
    // char *c_p = NULL;
    NODE(char)
    // i_p = (int *)malloc(sizeof(int));
    MALLOC(int)
    if ( int_p == NULL) 
    {
        printf("i_p malloc memory failed!\n");
        // 如果失敗直接退出,沒有問題
        goto ERR1;
    }
    // short_p = (short *)malloc(sizeof(short));
    MALLOC(short)
    if ( short_p == NULL) 
    {
        printf("s_p malloc memory failed!\n");
        // 如果失敗需要先將i_p指向的堆區(qū)空間釋放     
        goto ERR2;
    }
    // char_p = (char *)malloc(sizeof(char));
    MALLOC(char)
    if ( char_p == NULL) 
    {
        printf("c_p malloc memory failed!\n");
        // 如果失敗需要先將i_p和s_p指向的堆區(qū)空間釋放
        goto ERR3;
    }
    // 如果都分配成功,不使用時手動釋放,
    // 如果不手動釋放,當(dāng)進(jìn)行結(jié)束之后,系統(tǒng)也會進(jìn)行回收。
    free(char_p);
    free(short_p);
    free(int_p); 
    return 0;
ERR3:
    free(short_p);
ERR2:
    free(int_p);
ERR1:
    return -1;
}

5 memset()

#include <string.h>
void *memset(void *s, int c, size_t n);

功能:將s的內(nèi)存區(qū)域的前n個字節(jié)以參數(shù)c填入

參數(shù):

? s:需要操作內(nèi)存s的首地址

? c:填充的字符,c雖然參數(shù)為int,但必須是unsigned char , 范圍為0~255

? n:指定需要設(shè)置的大小

返回值:s的首地址

6 memcpy()

#include <string.h>
void *memcpy(void *dest, const void *src, size_t n);

功能:拷貝src所指的內(nèi)存內(nèi)容的前n個字節(jié)到dest所值的內(nèi)存地址上。

參數(shù):

? dest:目的內(nèi)存首地址

? src:源內(nèi)存首地址,注意:dest和src所指的內(nèi)存空間不可重疊,可能會導(dǎo)致程序報錯

? n:需要拷貝的字節(jié)數(shù)

返回值:dest的首地址

7 memcmp()

#include <string.h>
int memcmp(const void *s1, const void *s2, size_t n);

功能:比較s1和s2所指向內(nèi)存區(qū)域的前n個字節(jié)

參數(shù):

? s1:內(nèi)存首地址1

? s2:內(nèi)存首地址2

? n:需比較的前n個字節(jié)

返回值:

? 相等:=0

? 大于:>0

? 小于:<0

到此這篇關(guān)于C語言動態(tài)內(nèi)存分配和內(nèi)存操作函數(shù)使用詳解的文章就介紹到這了,更多相關(guān)C語言動態(tài)內(nèi)存分配內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • OpenCV邊緣提取算法流程的實(shí)現(xiàn)(附DEMO)

    OpenCV邊緣提取算法流程的實(shí)現(xiàn)(附DEMO)

    本文主要介紹了OpenCV邊緣提取算法流程的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-08-08
  • 減小VC6編譯生成的exe文件的大小的方法

    減小VC6編譯生成的exe文件的大小的方法

    這篇文章主要介紹了減小VC6編譯生成的exe文件的大小的方法,需要的朋友可以參考下
    2015-01-01
  • C語言用fstat函數(shù)獲取文件的大小方法

    C語言用fstat函數(shù)獲取文件的大小方法

    今天小編就為大家分享一篇關(guān)于C語言用fstat函數(shù)獲取文件的大小方法,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2018-12-12
  • c語言實(shí)現(xiàn)奇偶排序算法

    c語言實(shí)現(xiàn)奇偶排序算法

    這篇文章主要介紹了c語言實(shí)現(xiàn)奇偶排序算法,有需要的朋友可以參考一下
    2013-12-12
  • 在c和c++中實(shí)現(xiàn)函數(shù)回調(diào)

    在c和c++中實(shí)現(xiàn)函數(shù)回調(diào)

    如何在c和c++中實(shí)現(xiàn)函數(shù)回調(diào)呢?現(xiàn)在小編就和大家分享一下在c/c++中實(shí)現(xiàn)函數(shù)回調(diào)的示例代碼,需要的朋友可以參考下
    2013-07-07
  • C語言實(shí)現(xiàn)單詞小助手功能完善版

    C語言實(shí)現(xiàn)單詞小助手功能完善版

    這篇文章主要為大家詳細(xì)介紹了C語言實(shí)現(xiàn)單詞小助手功能的完善版,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-10-10
  • C++中spdlog的簡單使用示例

    C++中spdlog的簡單使用示例

    spdlog是一個開源、跨平臺、無依賴、只有頭文件的C++11日志庫,所以這篇文章主要來和大家介紹一下一個簡單的spdlog使用示例,感興趣的小伙伴可以了解一下
    2023-08-08
  • C/C++中的OpenCV讀取視頻與調(diào)用攝像頭

    C/C++中的OpenCV讀取視頻與調(diào)用攝像頭

    這篇文章主要介紹了C/C++中的OpenCV讀取視頻與調(diào)用攝像頭,具有很好的參考價值,希望對大家有所幫助。
    2022-11-11
  • C++實(shí)現(xiàn)LeetCode(77.Combinations 組合項(xiàng))

    C++實(shí)現(xiàn)LeetCode(77.Combinations 組合項(xiàng))

    這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(Combinations 組合項(xiàng)),本篇文章通過簡要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • OpenCV如何提取圖片中曲線

    OpenCV如何提取圖片中曲線

    這篇文章主要為大家詳細(xì)介紹了OpenCV如何提取圖片中曲線,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-01-01

最新評論

阳山县| 沽源县| 宜昌市| 九龙城区| 通辽市| 临猗县| 望江县| 辽阳市| 阿克苏市| 通河县| 兴国县| 九龙县| 安远县| 进贤县| 海阳市| 孝昌县| 株洲市| 麻江县| 岳阳县| 苍溪县| 乌鲁木齐县| 南阳市| 左贡县| 三亚市| 辉南县| 石嘴山市| 忻州市| 洛隆县| 湄潭县| 宕昌县| 夏河县| 祁阳县| 嘉义市| 内黄县| 武汉市| 修武县| 海城市| 雷州市| 涞源县| 大余县| 大荔县|