浅谈C程序的内存分配

来源:互联网 发布:学生管理系统设计c语言 编辑:程序博客网 时间:2024/05/23 02:05
我是个C语言的初学者,在C语言的学习中,也遇到了许多让人脑洞大的问题,今天就只先说说C程序的内存分配问题吧。在学指针这块的知识时,比如我们定义了一个指针:'char *str="hello_world"',我们都知道是计算机为指针str分配了内存空间,那么"hello_world"这个字符串是不是也被分配了内存空间呢,是不是指针和"hello_world"都在同一个内存空间呢?当时,我坚定的认为这个答案是肯定的,但当我尝试用'printf("%s",*str)'输出时,就出现问题了(程序会终止),又想通过sizeof操作符看一下它所占的字节数时,它的答案居然是char *指针的大小。这件事苦恼了我几天,直到知道了C的内存分配时,我的世界又一次明朗了起来。废话说的有点多了,下面就开始切入正题吧,先来段代码,大家先思考一下机器是如何分配内存给各个变量吧。#include<stdio.h>#include <stdlib.h>#include <string.h>int a = 0; char *p1; int main(void){    int b;     char s[] = "abc";     char *p2;     char *p3 = "123456";     static int c =0;     p1 = (char *)malloc(10);     p2 = (char *)malloc(20);     strcpy(p1, "123456");     return 0;}通过以下内容的介绍,希望大家都能有所收获吧。一般来说,我们都将C语言中内存分为五个区:1.栈(stack):用来存放函数的形参和函数内的局部变量。由编译器分配空间,在函数执行完后由编译器自动释放,。2.堆(heap):用来存放由动态分配函数(如malloc)分配的空间。是由程序员自己手动分配的,并且必须由程序员使用free释放。如果忘记用free释放,会导致所分配的空间一直占着不放,导致内存泄露。3.全局区/静态区:用来存放全局变量和静态变量。程序结束时由系统释放,分为全局初始化区和全局未初始化区;存在于程序的整个运行期间,是由编译器分配和释放的。4.文字常量区:常量字符串放于此,程序结束时由系统释放。例如char *str="hello_world";则"hello_world"为文字常量,存放于文字常量区。也由编译器控制分配和释放。5.程序代码区:用来存放程序的二进制代码。       下面就让我们将C语言各变量的分配区域注释出来吧。#include <stdlib.h>#include <string.h>int a = 0; //全局初始化区char *p1; //全局未初始化区int main(){    int b; //栈    char s[] = "abc"; //s在栈,"abc\0"在文字常量区    char *p2; //栈    char *p3 = "123456"; //"123456\0"在常量区,p3在栈上    static int c =0; //全局区    p1 = (char *)malloc(10); //p1在栈,分配的10字节在堆    p2 = (char *)malloc(20); //p2在栈,分配的20字节在堆    strcpy(p1, "123456"); //"123456"放在常量区,编译器可能会优化为和p3的指向同一块区域    return 0;}   至于其他的分配方式,比较来比较去,个人感觉都是大同小异,像《Unix环境高级编程》(著名的APUE)中提出,C程序的内存布局为Text,Data,BSS,Stack, Heap:1.Text是程序的代码段。2.Data是程序中初始化了的全局、静态数据变量。3.BSS是程序中未初始化的全局、静态数据变量。即使全局、静态数据变量初始化为0仍然是属于BSS段。(未初始化的数据段)4.Stack是程序中的局部变量,由高地址到低地址向下增长。5.Heap是malloc调用动态分配的内存,由低地址到高地址向上增长。总之,关于C语言的内存分配大概就这么多了。希望大家都能有收获吧。
3 0
原创粉丝点击