C语言内存区域划分

本文详细介绍了C语言中的不同内存区域,包括栈区(临时变量存储,栈溢出风险)、堆区(程序员手动分配,malloc/realloc管理)、全局/静态区(存储全局和静态变量,分为data和bss段)、常量区(存储常量数据)以及代码区(只读程序代码)。
摘要由CSDN通过智能技术生成

在C语言中,内存区域主要分为:

栈区(Stack):

1.由编译器自动分配和释放
2.利用栈存储一些临时变量,包括函数形参、函数内部局部变量、返回值等
3.栈的操作遵循“后进先出”(LIFO)的原则

看下面的程序:

#include <stdio.h>

int add(int a, int b)
{
	int result = a + b;
	
	return result ;
}

int main(int argc, const char *argv[])
{
	int x = 5;
	int y = 3;
	int sum = add(x,y);
	
	printf("&x=%p\n&y=%p\n&sum=%p\n", &x, &y, &sum);
	
	return 0;
}

main函数的x,y,sum都分配在栈上,add函数中,a,b,result也是分配在栈上,看一下运行结果:
在这里插入图片描述
sum的地址>y的地址>x的地址,说明栈是由高地址往低地址增长,而数据的写入是按低地址往高地址的顺序写入,所以,程序一旦没有对输入的数据做出限制,就会存在数据溢出当前栈的可能。

4.栈溢出(stack overflow),栈空间是有大小限制的,Linux系统可以用命令ulimit来查看,默认大小是8M。
在这里插入图片描述

堆区(Heap):

1.由程序员手动分配和释放的储存区
2.堆在内存中位于bss区和栈区之间
3.通过调用函数如malloc()、calloc()或realloc()来从堆中分配内存
4.必须手动调用free()函数来释放堆内存,否则可能导致内存泄漏

看下面的程序:

#include <stdio.h>
#include <stdlib.h>

int *create_array(int size)
{
	int i;
    int *p = (int *)malloc(size * sizeof(int));

    if (p == NULL)
    {
        printf("malloc failed\n");
    }
    
	for ( i = 0; i < size; i++)
    {
        p[i] = 10 + i;
    }
    
	return p ;
}

int main(int argc, const char *argv[])
{
	int i, n = 5;
    int *p = create_array(n);

    if (p == NULL)
    {
        return -1;
    }
    
	printf("p=%p\n", p);

    for ( i = 0; i < n; i++)
    {
        printf("%d\n", *(p+i));
    }
	
    free(p);
    p = NULL;
    
	return 0;
}

第7行malloc申请堆空间,第25行调用函数,第39行free释放堆空间。

全局(静态)区:

1.内存分配在程序编译之前完成,且在程序的整个运行期间都存在
2.存储全局变量和静态变量
3.静态内存区细分还可以分成:.data段和.bss段
data段:初始化的全局变量、静态变量和只读数据都存放在这个域。
bss段:未初始化的全局变量和静态变量。
未初始化的变量,是在程序中说明,在运行的初始化阶段,才会真正占用存储空间,它的大小不会影响目标文件的大小。总结,一些变量放在bss段,可以减小目标文件的占用空间。

看下面的程序:

#include <stdio.h>

int globalVar = 10;//全局变量存储在静态存储区

void modifyGlobalVar(void)
{
	static int count = 0;//静态变量也存储在静态存储区
	globalVar = 20;//可以在函数中修改全局变量的值
}

int main(int argc, const char *argv[])
{
	printf("Global variable:%d\n", globalVar);//输出全局变量的值

    modifyGlobalVar();//调用函数修改全局变量的值
    
    printf("Modified global variable:%d\n", globalVar);//输出修改后的全局变量的值

	return 0;
}

常量区:

1.常量存储区用于存储常量数据,如字符串常量,const修饰的变量
2.常量存储区通常位于静态存储区内

看下面的程序:

#include <stdio.h>

int main(int argc, const char *argv[])
{
	const int num = 10;//常量num存储在常量存储区
    char *str = "hello";//字符串常量存储在常量存储区

    printf("Constant variable:%d\n", num);//输出常量的值
    printf("String constant:%s\n", str);//输出字符串常量的值

	return 0;
}

代码区:

1.通常是用来存放程序执行代码的一块内存区域
2.该区域的大小在程序运行前就已经确定,并且内存区域通常属于只读

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: C 程序在执行时,通常会将内存大方向划分为四个区域: 1. 栈区(stack):用于存储函数的调用信息,包括函数的参数、局部变量等。栈是由编译器自动分配和释放的,是线程私有的。 2. 堆区(heap):用于动态分配内存,由程序员在程序运行时手动分配和释放。 3. 全局/静态区(global/static):存储全局变量和静态变量。 4. 代码区(text):存储程序的二进制代码。 这四个区域内存空间是由操作系统在程序启动时分配的。 ### 回答2: C 程序在执行时,将内存划分为4个区域,分别是栈区、堆区、全局/静态存储区和代码区。 首先是栈区,它用于存储局部变量和函数的参数。栈区的特点是内存分配和释放是自动进行的,随着函数的调用和返回而动态地分配和释放。栈区的大小是编译器事先确定的,一般比较小,而且速度快。栈区是一种临时存储方式,存储的数据在函数结束后会自动被销毁。 其次是堆区,它用于动态内存分配。堆区的特点是内存分配和释放需要手动进行。程序员通过调用malloc()、calloc()、realloc()等函数来手动申请堆区的内存,通过调用free()函数来释放堆区的内存。堆区的大小可通过调整代码来改变,它的内存空间较大,但是分配和释放内存的开销相对较大。 全局/静态存储区是用来存储全局变量和静态变量的。全局变量在程序的整个生命周期内都是存在的,而静态变量只在声明它的函数中可见。这两种变量都在程序启动时就分配内存,直到程序结束才被释放。全局/静态存储区通常是在程序的数据段中。 最后是代码区,它存储程序的指令和函数体等代码。代码区也是在程序启动时就分配内存,在程序结束时被释放。代码区的大小是由程序的代码量决定的。 总体来说,C 程序在执行时将内存大方向划分为栈区、堆区、全局/静态存储区和代码区,各个区域有着不同的特点和用途,同时也需要程序员在编码过程中合理地进行内存的分配和释放。 ### 回答3: C程序在执行时,将内存大方向划分为4个区域,分别是代码区、全局区、栈区和堆区。 代码区:也称为文本区,用于存储程序的机器指令,包括函数体、循环语句、条件语句等。这部分区域是只读的,当程序被加载入内存时,代码区的内容就已经确定,并且独立于程序的执行。 全局区:也称为静态数据区,用于存储全局变量、静态变量和常量。全局区的数据在程序的整个生命周期内都存在,直到程序结束才释放。 栈区:也称为运行时栈,用于存储函数的局部变量、参数和函数的返回地址。栈区的数据是按照先进后出(FILO)的原则存储的,每次函数调用时,会为局部变量分配一块存储空间,函数调用结束后,该空间将自动释放。 堆区:也称为动态数据区,用于存储动态分配的内存,例如通过malloc()函数或new运算符申请的内存。堆区的数据由程序员手动管理,需要释放不再使用的内存,否则会导致内存泄漏。 这四个区域在程序执行过程中扮演不同的角色。代码区存储程序的指令,全局区存储全局变量和常量,栈区存储函数的局部变量和参数,堆区存储动态分配的内存。这样的内存划分方案有助于管理程序的内存资源,使程序在执行时更加高效和可靠。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值