关于堆栈的讲解(一)

1、 堆和栈基本概念: (来自网上)

简单的来讲堆(heap)上分配的内存,系统不释放,而且是动态分配的。

栈(stack)上分配的内存系统会自动释放,它是静态分配的。栈的分配是从内存的高地址向低地址分配的,而堆则相反(好像这里说错了,堆本来就是 链式存储,哪里来的高到低,低到高)。12:33:14  对的,链表本来就是由 低地址 向 高地址 遍历。。

由malloc或new分配的内存都是从heap(堆)上分配的内存,从heap(堆)上分配的内存必须有程序员自己释放,用free来释放,否则这块内存会一直被占用而得不到释放,就出现了“内存泄露(Memory Leak)”。

这样会造成系统的可分配内存的越来越少,导致系统崩溃。(可以写恶意程序,让系统崩溃吧^*^)

 

 

2、预备知识

一个由c/C++编译的程序占用的内存分为以下几个部分

      1、栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。

      2、堆区(heap) — 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表,呵呵。

      3、全局区(静态区)(static)—,全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。 - 程序结束后有系统释放

      4、文字常量区 —常量字符串就是放在这里的。 程序结束后由系统释放,放在代码段

      5、程序代码区—存放函数体的二进制代码。

 

1、

#include<stdio.h>
#include<string.h>
#include<malloc.h>

int a = 0; //全局初始化区

char *p1; //全局未初始化区 0x0000 0000    在 BSS 段

main()

{

int b=3; // 栈          显然在 栈 ,存放局部变量的值

 

char s[] = "abc "; //栈地址  也是局部变量 ,只不过是数组   

 

 

 

char *p2; //栈 P2地址是 0x12ff70,说明是对的 

 

char *p3 = "123456 "; //123456/0在常量区,p3在栈上,地址是 0x12ff6c,但是 123456 是放在常量区的 ,所以说和 上面的数组s[]还是有一点区别的,数组里面放在 栈区 , 指针指向的 放在常量区(不能理解的是 这里的常量区究竟是 代码段还是 数据段

 

我的理解是在 代码段吧!!网上说(在代码段中,也有可能包含一些只读的常数变量,例如字符串常量等。)

     

 

所以我们来验证了一下,令 *(p+1)='4'  也就是打算 把 ‘123456’中的 2 改为 '4',然后如下图,所以说 不能 写,所以说 是常量在 代码段,也不可以写。

 



static int c =0; //全局(静态)初始化区   

 

p1 = (char *)malloc(10); // 放在了 堆区    

 

 

p2 = (char *)malloc(20); //分配得来得10和20字节的区域就在堆区。    

 

strcpy(p1, "123456 "); //123456/0放在常量区,编译器可能会将它与p3所指向的 "123456 "优化成一个地方。    

 

}

 

好难,自己理解吧!!!!

 

常量区 文本段 代码段   堆区  全局静态区(也叫数据段)              
 都说代码段不可写,但我                      
感觉可以写啊??why       c    0x004225a0                
这里你理解错了,这里可以叫                      
代码段  又可以叫 文本段,这得看自己怎么定义      开始的 &p1 0x4225a4 B0          p3  0x0012ff6c  1c

比如:  AREA RESET, CODE, READONLY  

                                      1c           它指向的 123456  在常量区  f0  
 AREA伪指令用于定义一个代码段在这里,自然只读       43            41   
 如果定义数据段,就可以修改了,有没有 const    p2  0x00431c70   00            00  
0x0041f01c 31   ' 1 '                p2   0x0012ff70 cc   
  32    '2'                 cc   
  33     3                  cc   
  34     4                 cc  
  35     5                s    0x0012ff74 61  a  
  36     6                 62  b   
    这里是用了  strcpy                63  c  
     p1  0x00431cb0  存放 '123456'               20  空格   
                      00  '\0'  
                    cc  
                    cc  
                    cc  
                  b     0x0012ff7c 03  
                  应为是 int 占 四个字节 00   
                    00   
                    00   

 

你懂了吗?     由于 p1 p2 在堆里面,所以 最后添加 free(p1), free(p2)  ,释放它的内存。

还有疑问:  为什么 是 0x12ff74 而不是 0x12ff78   ,很纠结,还望大神能够指教。78坑定不行的,放不下,好像计算机讲 要 对齐 什么的,不太懂唉,就这样吧,有大神讲讲啊。求助

 疑问 

p1 = (char *)malloc(10); // 放在了 堆区       p1  0x00431cb0

p2 = (char *)malloc(20);  //  也放在了 堆区   ,不是说 堆区应该由 低地址向高地址来链式存储吗  。     p2  0x00431c70   , 不是应该 p1 在低位的么??? why

 

2、   第二个  问题 比较 

 

posted on 2015-10-17 11:23  无悔这一生。  阅读(493)  评论(0编辑  收藏  举报

导航