C语言一一内存分配

C语言作为一门应用广泛、功能强大、使用灵活的面向过程的编程语言。所以在内存管理方面能够加深我们对程序的理解。有助于开发高效的应用。

内存的组成

对于一个由C语言编写的程序而言,内存主要可以分为以下5个组成部分:

在这里插入图片描述
注意:

代码段、数据段、BSS段程序编译期间由编译器分配内存空间,在程序启动加载时,由于未初始化的全局变量存放在BSS段,已初始化的全局变量存放在数据段,所以程序中因应该尽量少使用全局变量。以节省程序的编译和启动时间。

变量的内存分配

栈(stack)

首先栈应该是数据结构中的一种线性结构被介绍,其具有先进后出特性(简称FILO)。

栈区类似于手枪中的弹夹,最先放进去的子弹,最后才被弹出,最后放进入的子弹最先弹出。其次栈作为内存中存储结构,通常存放程序临时创建的局部变量。

下面给出如何实现一个栈:

#include <stdio.h>

#define STACK_SIZE 64  //栈大小
#define TOP_OF_STACK -1 //栈顶位置

int stack_push(char* stack,int top,int value);
int stack_pop(char * stack,int top);
int stack_is_empty(int top);
int stack_is_full(int top);

//入栈
int stack_push(char* stack,int top,int value)
{
    if (stack_is_full(top)) 
    {
        printf("栈满\n");
        return -1;
    }

    stack[++top]=value;
    printf("入栈元素:%d\n",stack[top]);
    return top;
}

//出栈
int stack_pop(char * stack,int top)
{
    if (stack_is_empty(top)) 
    {
        printf("空栈\n");
        return -1;
    }
    printf("出栈元素:%d\n",stack[top]);
    top--;
    return top;
}

int stack_is_empty(int top)
{
    return top ==  - 1;
}

int stack_is_full(int top)
{
    return top == STACK_SIZE - 1;
}


int main(int argc, char **argv) 
{
    char stack[100];
    int top = TOP_OF_STACK;  //栈顶位置
    top=stack_push(stack, top, 1);
    top=stack_push(stack, top, 2);
    top=stack_push(stack, top, 3);
    top=stack_push(stack, top, 4);

    top=stack_pop(stack, top);
    top=stack_pop(stack, top);
    top=stack_pop(stack, top);
    top=stack_pop(stack, top);
    top=stack_pop(stack, top);

    return 0;
}

如果想更深入的理解数据结构中的栈,可以参考栈的实现

栈顶的地址和栈的最大容量一般是由系统预先规定好的,通常不会太大。由于栈中主要存放是局部变量,而局部变量的占用内存空间是其所在的代码段或函数段结束时由系统回收重新利用。所以栈的空间是循环利用自动管理的,一般不需要人为操作。

注意:

不宜在栈中申请过大的空间,比如长度很大的数组,递归调用重复次数很多的函数等等。

堆(heap)

通常存放程序运行中动态分配的存储空间。堆是低地址向高地址扩展的数据结构,是一块不连续的内存区域。在标准C语言上,使用malloc等内存分配函数是从堆中分配内存的,在Objective-C中,使用new创建的对象也是从堆中分配内存的。

动态分配内存空间例子:

#include <stdio.h>
#include <stdlib.h> //malloc,free,rand

int main(int argc, char const *argv[])
{
	
	int input;
	int i ;

	printf("Please enter the length of the string:");

    scanf("%d",&input);

    char *buf = (char *) malloc(input + 1);//字符最后包含'\0'
    if (buf == NULL)
    {
    	printf("malloc failed!\n");
    	return -1;
    }

	//随机生成字符串

	for ( i = 0; i < input; i++)
	{
		buf[i] = rand()%26 +'a';
	}

	buf[i] = '\0';

	printf("A randomly generated string: %s\n",buf);
	free(buf);

	return 0;
}

输出结果:
在这里插入图片描述
堆内存是操作系统划分给堆管理器来管理的,管理器向使用者(用户进程)提供API(malloc和free等)来使用堆内存。需要程序员手动分配释放,如果程序员在使用完申请后的堆内存却没有及时把它释放掉,那么这块内存就丢失了,这就是所谓的–内存泄漏

BSS段

Block Started by Symbol的简称,通常是指用来存放程序中未初始化的全局变量和静态变量。

数据段

通常是指用来存放程序中已初始化的全局变量和静态变量以及字符串常量。

代码段

通常是指用来存放程序执行代码的一块内存区域。这部分区域的大小在程序运行前就已经确定。

发布了71 篇原创文章 · 获赞 42 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/chen1415886044/article/details/104099602
今日推荐