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\n",a,b);
    swap(a,b);
    printf("a:%d,b:%d\n",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\n",a,b);
    swap(&a,&b);
    printf("a:%d,b:%d\n",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++基礎學完,然后深入學習數據結構和算法了

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM