美文网首页
指针篇 | 不懂内存的算法工程师不是好司机

指针篇 | 不懂内存的算法工程师不是好司机

作者: yuanCruise | 来源:发表于2019-05-28 00:36 被阅读0次

想要构建一个算法工程,尤其是落地到设备端,C语言显然是不二之选,而内存是我们学习C语言永远绕不过的一道坎。但事实上,内存并没有我们想象中的那么可怕。本文中,我们姑且把内存分为四个区域:代码区,常量区,堆区,栈区。

简单介绍下内存四区:
1.代码区:该内存用于存放代码段。
2.常量区:该内存用于存放各类常量,如字符串常量等。
3.堆区:该内存用于存放用户自己开辟的空间,用户不手动释放,该内存就一直存在。(好用的同时需要注意内存泄漏)
4.栈区:该内存用于存放临时变量和函数入口地址,编译器自动分配自动释放。


1.常量区
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

char * getStr1()
{
    char *p1 = "YLYL";
    return p1;
}
char *getStr2()
{
    char *p2 = "YLYL";
    return p2;
}

void main()
{
    char *p1 = NULL;
    char *p2 = NULL;
    p1 = getStr1();
    p2 = getStr2();

    //打印p1 p2指针变量 所指向内存空间的数据
    printf("p1:%s , p2:%s \n", p1, p2);

    //打印p1 p2 指针的值
    printf("p1:%d , p2:%d \n", p1, p2);

    return ;
}


本文通过字符串常量来介绍下常量区的特征,从图中我们可以总结出指针的两个要点:
1.指针的指向哪里,就把哪里的地址赋值给指针变量。
2.指针变量的值,和指针指向的内存空间的值是完全不同的概念。如上图中,指针变量的值是0x1314,而指针指向的内存空间的值是YLYL。
通过打印指针变量的值,我们发现两个函数中相同的字符串常量在内存空间中有着相同的地址(这其实是编译器在编译阶段所做的优化)。

2.堆区
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

//利用malloc分配内存
char *getMem(int num)
{
    char *p1 = NULL;
    p1 = (char *)malloc(sizeof(char) * num);
    if (p1 == NULL)
    {
        return NULL;
    }
    return p1;
}
void main()
{
    char *tmp = NULL;
    tmp = getMem(10);
    if (tmp == NULL)
    {
        return ;
    }
    strcpy(tmp, "YLYL"); //向tmp做指向的内存空间中copy数据

    printf("tmp:%s.\n", tmp);
    return ;
}

如上述代码和示意图所示,P1指针变量是临时变量,所以定义在栈空间上,因此getMem函数退出后,P1的空间将会被自动释放掉,但是在释放的同时,P1指针变量的值先一步赋值给了tmp指针变量,而该指针变量所指向的是堆内存,因此不会被释放,从而实现了内存空间的创建,这就是堆空间的特性~

3.栈区
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

char *getMem(int num)
{
    char *p1 = NULL;
    p1 = (char *)malloc(sizeof(char) * num);
    if (p1 == NULL)
    {
        return NULL;
    }
    return p1;
}

char *getMem_stack()
{
    char buf[64]; //临时变量 栈区存放
    strcpy(buf, "YLYL_2");
    return buf;
}

void main()
{
    char *tmp = NULL;
    tmp = getMem(10);
    if (tmp == NULL)
    {
        return ;
    }
    strcpy(tmp, "YLYL_1"); //向tmp做指向的内存空间中copy数据

    tmp = getMem_stack();

    printf("tmp:%s.\n", tmp);
    return ;
}

如上述代码和示意图所示,buf数组是临时变量,所以定义在栈空间上,因此getMem函数退出后,buf首地址所指向的空间将会被自动释放掉,存储的值也就相应的被释放了。因此即使,buf首地址先一步赋值给了tmp指针变量,但也无法获取对应的值,这就是栈空间的特性~

相关文章

  • 指针篇 | 不懂内存的算法工程师不是好司机

    想要构建一个算法工程,尤其是落地到设备端,C语言显然是不二之选,而内存是我们学习C语言永远绕不过的一道坎。但事实上...

  • 指针篇 | 不懂内存的算法工程师不是个好厨子

    经常会总结指针的用法和注意点,由于工作中基于学习到的深度学习网络模型构建功能时会遇到各种指针的使用,在实践中终于明...

  • 深浅拷贝

    野指针: 指向不可用内存区域的指针不是NULL指针,是指向"垃圾"内存的指针 原因: 指针变量没有被初始化 指针指...

  • C语言基础及指针③函数与二级指针

    接续上篇 C语言基础及指针②之指针内存分析 在上一篇中 , 我们分析了指针在内存中是怎样存储的 , 以及它是怎样操...

  • Go指针(一)

    很多小伙伴将内存和指针混为一谈。你是不是也是呢?内存地址是内存中每个字节单元的唯一编号,而指针则是一个实体。指针会...

  • 空指针、野指针与悬垂指针

    空指针:指针指向的地址为空的指针叫空指针(NULL指针) 野指针:是指向“垃圾”内存(不可用内存)的指针产生原因:...

  • 06.C(指针)

    (创建于2017/8/17) 指针的含义 指针的步长 指针运算,不是简单的整数加减法,而是指针指向的数据类型在内存...

  • 空指针 野指针与悬垂指针

    一:空指针 指针指向的地址为空的指针叫空指针(NULL指针) 二:野指针 是指向“垃圾”内存(不可用内存)的指针产...

  • C语言、C++基础

    首先,指针和数组完全是两个东西,虽然它们看起来和内存地址的关系很类似! 指针变量:表示指向内存地址的指针,但不是内...

  • 函数指针-函数指针-案例-动态分配内存-重新分配内存-内存泄漏

    1、函数指针2、函数指针-案例3、动态分配内存4、重新分配内存5、内存泄漏 1、函数指针 2、函数指针-案例 3、...

网友评论

      本文标题:指针篇 | 不懂内存的算法工程师不是好司机

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