欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

 更新時間:2022年12月27日 08:43:59   作者:編程遠(yuǎn)泊  
但是在實際的編程中,往往會發(fā)生這種情況,即所需的內(nèi)存空間取決于實際輸入的數(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)進程結(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ū)空間的首地址
失?。悍祷豊ULL

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));
    // 對返回值進行判斷
    if(m_p == NULL) {
        printf("malloc memory failed!\n");
        return -1;
    }
    printf("malloc memory successed!\n");
    // 對m_p指針指向的堆區(qū)空間進行初始化
    *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ū)進行初始化,然后使用冒泡排序的方式對堆區(qū)空間中的成員進行排序。使用多文件編程的方式實現(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 是因為每趟都可以少比較一個元素
			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)進行結(jié)束之后,系統(tǒng)也會進行回收。
    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)進行結(jié)束之后,系統(tǒng)也會進行回收。
    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)文章

  • C語言實現(xiàn)打飛機小游戲

    C語言實現(xiàn)打飛機小游戲

    這篇文章主要為大家詳細(xì)介紹了C語言實現(xiàn)簡單的打飛機小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-02-02
  • C++實現(xiàn)LeetCode(49.群組錯位詞)

    C++實現(xiàn)LeetCode(49.群組錯位詞)

    這篇文章主要介紹了C++實現(xiàn)LeetCode(49.群組錯位詞),本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • Qt實現(xiàn)給窗口繪制陰影的示例代碼

    Qt實現(xiàn)給窗口繪制陰影的示例代碼

    這篇文章主要為大家詳細(xì)介紹了Qt實現(xiàn)給窗口繪制陰影的方法,文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)Qt有一定的幫助,感興趣的可以了解一下
    2022-11-11
  • C++中Boost庫裁剪與其應(yīng)用詳解

    C++中Boost庫裁剪與其應(yīng)用詳解

    大家都知道STL全稱"標(biāo)準(zhǔn)模板庫(Standard Template Library)",其實它是一套標(biāo)準(zhǔn),可能有不同的實現(xiàn),它是 C++ 的"標(biāo)準(zhǔn)庫"。Boost 則是一個 C++ 庫,被稱為"C++ 準(zhǔn)標(biāo)準(zhǔn)庫"。那么這篇文章文章我們就來詳細(xì)的介紹C++Boost庫的裁剪與其應(yīng)用,感興趣的朋友可以一起學(xué)習(xí)。
    2016-10-10
  • 簡單掌握C++中的函數(shù)模板

    簡單掌握C++中的函數(shù)模板

    這篇文章主要介紹了C++中的函數(shù)模板,包括函數(shù)模板的聲明和生成以及異常處理等基本知識,需要的朋友可以參考下
    2016-04-04
  • 奇怪的C語言特性

    奇怪的C語言特性

    下面列出的特性未必奇怪,有的算是有趣
    2013-04-04
  • C++ 指向類成員的指針

    C++ 指向類成員的指針

    指向類成員的指針總的來講可以分為兩大類四小類(指向數(shù)據(jù)成員還是成員函數(shù),指向普通成員還是靜態(tài)成員)
    2020-03-03
  • 深入探究C/C++中互斥量(鎖)的實現(xiàn)原理

    深入探究C/C++中互斥量(鎖)的實現(xiàn)原理

    ? 互斥量是一種同步原語,用于保護多個線程同時訪問共享數(shù)據(jù),互斥量提供獨占的、非遞歸的所有權(quán)語義,本文將和大家一起深入探究C/C++中互斥量(鎖)的實現(xiàn)原理,感興趣的小伙伴跟著小編一起來看看吧
    2024-06-06
  • c語言實現(xiàn)足球比賽積分統(tǒng)計系統(tǒng)

    c語言實現(xiàn)足球比賽積分統(tǒng)計系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了c語言實現(xiàn)足球比賽積分統(tǒng)計系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-05-05
  • C語言實現(xiàn)棧的示例詳解

    C語言實現(xiàn)棧的示例詳解

    棧是一種特殊的線性表,只允許從一端進出數(shù)據(jù),稱為后進先出,先進后出。本文主要為大家介紹了C語言實現(xiàn)棧的示例代碼,感興趣的可以了解一下
    2022-06-06

最新評論