zoukankan      html  css  js  c++  java
  • C语言程序猿必会的内存四区及经典面试题解析

    前言:

        为啥叫C语言程序猿必会呢?因为特别重要,学习C语言不知道内存分区,对很多问题你很难解释,如经典的:传值传地址,前者不能改变实参,后者可以,知道为什么?还有经典面试题如下: 

    #include <stdio.h>
    #include <stdlib.h>
    #include <stdlib.h> void getmemory(char *p) { p=(char *) malloc(100); } int main( ) { char *str=NULL; getmemory(str); strcpy(str,"hello world"); printf("%s/n",str); free(str); return 0; }

      这段代码执行了会怎么样?接下里我会解释这道面试题。

      一、内存布局

      可能网上有很多把内存分的很多、很细,但觉得很难记,并对于理解问题作用并不大。现在主要将内存分为四区如下:

      代码区:存放代码;运行期间不可修改

      全局区:全局变量、静态变量、常量字符串;程序运行时存在,退出时消失。

      栈区:自动变量、函数参数、函数返回值;作用域函数内(代码块内)

      堆区:动态分配内存,需手动释放

      用交换两个数的程序进行解释吧,如下: 

    #include<stdio.h>
    
    void swap(int a,int b)
    {
        int temp = a;    //
        a = b;
        b =temp;
    }
    int main()
    {
        int a=1,b=2;    //
        printf("a:%d,b:%d
    ",a,b);
        swap(a,b);
        printf("a:%d,b:%d
    ",a,b);
    
        return 0;
    }

      画个图进行讲解,如下:  PS:依旧是全博客园最丑图,不接受反驳!

      

      说明:main函数把a,b的值给了temp函数,temp函数在内部交换了值,并没有影响main函数,并且temp结束,栈上的数据释放。传值不会改变实参。

      二、程序示例及面试题讲解

      1、传地址交换两个数  

       在拿传指针的例子来说明一下,如下:

    #include<stdio.h>
    
    void swap(int *a,int *b)
    {
        int temp = *a;    //
        *a = *b;
        *b =temp;
    }
    int main()
    {
        int a=1,b=2;    //
        printf("a:%d,b:%d
    ",a,b);
        swap(&a,&b);
        printf("a:%d,b:%d
    ",a,b);
    
        return 0;
    }

      结果:成功交换了实参的值

      用图进行解释,如下:  PS:依旧是全博客园最丑图,不接受反驳!

      

      说明:实参把地址传给形参,形参*a、*b是取的实参在内存中的值,交换也就是交换实参的值了,所以成功交换了实参的值。

      2、解释面试题

      程序就是最开始的面试题那个,不再列出来了。

      结果:段错误

      然后画图进行说明,如下:  PS:依旧是全博客园最丑图,不接受反驳!

      

      说明:最重要一点实参是把值传给形参,而不是地址,要理解这一点!就是把实参的NULL给了形参,然后getmemory在堆上开辟空间,结束时p被释放了,但main函数中的str并没有指向堆上的内存,再给strcpy,当然会段错误。

      三、解决被调函数开辟空间

      可能有人就问了,我就想让被调函数开空间,怎么办呢?那就需要形参是二级指针了。

      给大家演示一下,代码如下:

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    void getmemory(char **p)
    {
    *p=(char *) malloc(100);
    }
    int main( )
    {
    char *str=NULL;
    getmemory(&str);
    strcpy(str,"hello world");
    printf("%s/n",str);
    free(str);
    return 0;
    }

      结果:没有段错误了

      大家可以自己画下图,不懂欢迎随时留言。

      三、十月份计划

      十月份需求会很忙,但也要抽出时间把C++基础学完,然后深入学习数据结构和算法了

      

  • 相关阅读:
    freemarker时间转换197
    用FileZilla服务器端和客户端实现本机与虚拟机之间文件上传和下载197
    springboot pom 详解197
    eclipse svn197
    eclipse 安装git197
    listen()函数中backlog参数分析
    linux 函数库使用
    gdb调试问题汇总
    gdb调试多线程
    linux-C 多线程编程
  • 原文地址:https://www.cnblogs.com/liudw-0215/p/9753687.html
Copyright © 2011-2022 走看看