美文网首页
12-C语言内存管理

12-C语言内存管理

作者: 低头看云 | 来源:发表于2018-09-17 08:59 被阅读0次

内存空间

进程空间图示

image

栈内存(Stack)

  • 栈中可以存放任意类型的变量, 即自动类型的局部变量, 随用随开,用完即消.
  • 栈内存分配从地址大的开始分配
  • 栈的内存大小有限, 所以特别在使用递归的时候一定要注意, 栈的溢出问题;
#include <stdio.h>

int main()
{
    // 存储在栈中, 内存地址从大到小
    int a = 10;
    int b = 20;
    printf("&a = %p\n", &a); // &a = 0060FEAC
    printf("&b = %p\n", &b); // &b = 0060FEA8

    return 0;
}

堆内存(Heap)

  • 堆内存可以存放任意类型的数据, 但需要自己申请与释放
  • 堆大小, 想象中的无穷大, 但实际使用中, 受限于实际内存的大小和内存是否连续性;
#include <stdio.h>
#include <stdlib.h>

int main()
{
    // 存储在栈中, 内存地址从小到大
    int *p1 = malloc(4);
    *p1 = 10;
    int *p2 = malloc(4);
    *p2 = 20;
   
    printf("p1 = %p\n", p1); //  p1 = 00762F48
    printf("p2 = %p\n", p2); // p2 = 00762F58

    return 0;
}


malloc函数

  • 格式: void * malloc(size_t _Size);

  • malloc函数作用: 用于申请堆中的内存的

  • malloc函数开辟好的存储空间,不会进行初始化

  • free函数: 释放我们在堆内存中开辟的一块内存空间

  • memset 函数: 给指定的堆内存进行初始化

  • 申请4个字节的存储空间

    • (int *)强制类型转换
    • malloc函数返回的是void * ,而我们开辟的是4个字节,正好是int类型,
    • 所以最好将void *转换为int *,因为只有指针类型是int 类型
    • 将来操作这块内存的时候,我们才知道应该操作多少个字节
    int *p = (int *)malloc(sizeof(int));
    printf("*p = %i\n", *p);
    
  • 小例子

#include <stdio.h>

int main()
{
    // 强制类型转换
    int *p1 = (int *)malloc(4);
    int *p2 = (int *)malloc(sizeof(int));
    *p1 = 123;
    *p2 = 456;
    printf("*p1 = %i\n", *p1);
    printf("*p2 = %i\n", *p2);

    printf("p1 = %i\n", p1);   // 10162952  观察可知,从低地址开始存放
    printf("p2 = %i\n", p2);   // 10162968
    
    // 通过free函数来手动释放我们申请的空间
    free(p1);
    free(p2);
    // free函数,我们只传递了内存的地址,系统如何知道应该释放多少个字节的存储空间
    // 在利用,malloc分配的时候,系统就保存了该指针对应的内存大小;
    return 0;
}


  • 注意点:

    • 使用malloc函数必须导入一个头文件 stdlib.h
    • 通过malloc申请的空间默认存储的是垃圾数据, 也就是系统不会帮我们初始化
    • 所以一般情况下, malloc都会和memset函数结合起来使用
  • memset作用:

    • 格式: memset(void *_Dst, int _Val, size_t _Size)
    • 专门用于初始化一块内存空间
    • 第一个参数: 传入需要初始化内存的地址
    • 第二个参数: 传入需要初始化的值
    • 第三个参数: 传入需要初始化的长度
  • memset注意: 使用时必须导入一个头文件string.h

#include <stdio.h>

int main()
{
    int *p = (int *)malloc(3 * sizeof(int));
    printf("p[0] = %i\n", p[0]);  // 垃圾数据
    printf("p[1] = %i\n", p[1]); // 垃圾数据
    printf("p[2] = %i\n", p[2]); // 垃圾数据

    memset(p, 0 , 3*sizeof(int));
    for(int i = 0; i < 3; i++){
        printf("p[%i] = %i\n", i, p[i]); // 0 0 0
    }
    return 0;
}

calloc函数

  • calloc函数 就是对malloc的封装
  • 格式: void *calloc(size_t nmemb, size_t size);
    • 第一个参数: size_t nmemb 所需内存单元数量
    • 第二个参数: size_t size 内存单元字节数量
    • 返回值: void * 成功返回非空指针指向申请的空间 ,失败返回 NULL
int *p = (int *)calloc(3, sizeof(int));
// 告诉操作系统,需要开辟3块存储空间, 每块存储空间占用4个字节

realloc函数

  • 例如, 我们利用malloc分配4个字节, 如果4个字节不够用,则想进行扩容,这时候可以使用realloc,反之,缩小也可以

  • 注意点:

    • 利用malloc函数分配存储空间,必须是连续的,也就是在堆内存中分配内存空间必须是连续的
    • 如果利用realloc函数扩容的时候,后面没有连续的内存, 那么系统会分配一块新的内存;

相关文章

  • 12-C语言内存管理

    内存空间 进程空间图示 栈内存(Stack) 栈中可以存放任意类型的变量, 即自动类型的局部变量, 随用随开,用完...

  • Go语言——内存管理

    Go语言——内存管理 参考: 图解 TCMalloc Golang 内存管理 Go 内存管理 问题 内存碎片:避免...

  • About AutoReleasePool

    1、所有语言从内存管理上来说分两种,自动内存管理和非自动内存管理。自动内存管理不需要开发者回收内存,语言会带垃圾回...

  • Objective-C 内存管理基础

    前言 之前的两篇拙文C语言-内存管理基础、C语言-内存管理深入 介绍了关于C语言在内存管理方面的相关知识。但是对于...

  • JavaScript 内存机制

    每种编程语言都有它的内存管理机制,比如C语言这样的底层语言,有原生内存管理接口,像malloc()动态的分配内存空...

  • 谈谈js中的内存机制——垃圾回收机制

    内存管理机制就是分配内存管理,每种编程语言都有它的内存管理机制,JavaScript的内存管理机制是:内存基元在变...

  • 学了指针没学动态内存一切都白搭!C语言基础教程之内存管理

    C语言内存管理 本文将讲解 C 中的动态内存管理。C 语言为内存的分配和管理提供了几个函数。这些函数可以在头文件中...

  • 文档链接2

    JVM内存管理------JAVA语言的内存管理概述: http://www.cnblogs.com/zuoxia...

  • Python深入06 Python的内存管理

    语言的内存管理 语言的内存管理是语言设计的一个重要方面。它是决定语言性能的重要因素。无论是C语言的手工管理,还是J...

  • JVM的大管家:自动内存管理机制

    和C语言手动管理内存不同,JVM实现了自动内存管理机制,这也是Java语言的一大特点。 简而言之,JVM自动内存管...

网友评论

      本文标题:12-C语言内存管理

      本文链接:https://www.haomeiwen.com/subject/hfwhnftx.html