[C언어]--C언어 메모리의 5대 영역인 스택 영역, 힙 영역, 전역 영역, 상수 영역, 코드 영역을 이해하는 글

목차

1 C 언어의 메모리 파티션

1.1 5개의 메모리 파티션

1.2 메모리 파티션 소개

1.2.1 스택 영역(stack)

1.2.2 힙 영역(힙)

1.2.3 (글로벌) 정적 영역

1.2.4 상수 면적

1.2.5 코드 영역

만들기가 쉽지 않은데 이 블로그가 도움이 되셨다면 댓글 + 좋아요 부탁드립니다.


C 언어는 한동안 학습해 왔으며 오늘은 C 언어 메모리의 다섯 가지 주요 영역을 요약하려고 합니다. C 언어를 심도 있게 이해하는 것은 우리에게 매우 필요한 지식 포인트입니다. 5대 영역을 이해하면 C언어의 최하위 계층을 더 익히는 데 큰 도움이 된다.

1 C 언어의 메모리 파티션

1.1 5개의 메모리 파티션

C 언어 메모리는 아래 그림과 표와 같이 크게 다섯 영역으로 나눌 수 있습니다.

메모리 이미지 영역 콘텐츠  권한
스택 영역 함수의 일반 변수 읽기 및 쓰기 가능
힙 영역 동적으로 할당된 메모리 읽기 및 쓰기 가능
(글로벌) 정적 변수 영역 정적 수정 변수 읽기 및 쓰기 가능
일정한 면적 변수 초기화를 위한 상수 읽기 전용
코드 영역 코드 명령 읽기 전용

nt k=1;
void main()
{
	int i=1;
	char *j;
	static int m=1;
	char *n="hello";
 
	printf("栈区地址为:0X%x\n",&i);		
	j = (char*)malloc(2); //一般不确定需要多大空间的时候用
	free(j);//及时释放
	printf("堆区地址为:0X%x\n",j);
	printf("全局变量地址为:0X%x\n",&k);
	printf("静态变量地址为:0X%x\n",&m);
	printf("文字常量区地址为:0X%x\n",n);
	printf("程序区地址为:0X%x\n",&main);
}
 
	char *i="hello";
	char j[10]="hello";
	printf("0X%x\n",i); //存放在文字常量区
	printf("0X%x\n",j); //存放在栈区
	j[1]='*';//可以直接赋值
	//*(i+1)='*'; //等价于i[1]='*';
	//不可以这样赋值, 因为i是指针,指向的是文字常量区,里面的内容是不能修改的
	i=j; //这样可以
	printf("%s\n",i);
	printf("%x\n",i);
	j=i;//这样不可以,因为j虽然也是地址,但是不是指针变量,不能直接赋值

1.2 메모리 파티션 소개

1.2.1 스택 영역(stack)

栈区컴파일러에 의해 자동으로 할당 및 해제되며 수동 관리 없이 운영 체제에서 자동으로 관리됩니다.
스택의 콘텐츠는 함수 범위 내에만 존재하며 함수 실행이 완료되면 콘텐츠가 자동으로 소멸됩니다.

#include<stdio.h>
char *getMem()
{
	char buf[64]; //局部变量 栈区存放
	strcpy(buf, "123456789");//向buf所代表的内存中写入内容
	//printf("buf:%s\n", buf);
	return buf;//返回所分配内存区域的第一个元素的地址
}
 
void main()
{
	char *tmp = NULL;
	tmp = getMem(10);
	if (tmp == NULL)
	{
		return ;
	}
	printf("tmp:%s\n", tmp);//输出tmp:
	system("pause");
	return ;
}

메모리 분석:

      

 

  • 스택 영역은 由高到低메모리 주소 방향으로 커지며 최대 크기는 컴파일 시 결정되며 속도는 빠르지만 자유도가 떨어지고 최대 공간이 크지 않다.
  • 스택 영역은 先进后出집의 가장 안쪽에서 먼저 들어가는 사람은 막고, 나중에 들어가는 사람은 문에서 막고, 문으로 들어가는 사람은 풀릴 때 먼저 나가는 것을 원칙으로 합니다.
  • 스택 스토리지 콘텐츠

  • 스택 영역에 임시로 생성되어 局部变量저장 됩니다.const定义的局部变量
  • 함수가 호출되어 반환되면 합계 入口参数返回值스택 영역에 저장됩니다.

평신도의 관점에서:

스택 영역은 함수 내부에 정의된 int a, int b, const int a, char p, char arr[ ] 등의 로컬 변수를 저장하는 데 사용되며, 함수의 형식 매개변수 등이 스택 영역에 저장된다. 스택 영역의 데이터는 컴파일러에서 관리하며 호출 후 자동으로 해제되어 스택으로 푸시되고 스택에서 팝됩니다. 예를 들어 함수 호출을 실행할 때 선입선출의 원칙에 따라 컴파일러는 먼저 다음 코드의 주소를 스택에 푸시한 다음 호출한 함수의 일부 로컬 변수, 형식 매개변수 등을 스택에 푸시하고 함수 호출이 완료될 때까지 기다립니다. 스택은 호출한 함수 이전에 스택에 푸시된 모든 변수와 형식 매개변수를 지우고 다음 코드의 주소에 따라 프로그램을 실행하며 후속 프로그램도 이와 같이 실행됩니다. 스택 영역의 크기는 일반적으로 약 1M이므로 너무 큰 배열을 정의하지 마십시오.
 

1.2.2 힙 영역(힙)

堆区메모리는 프로그래머가 할당하고 해제합니다. 프로그래머가 해제하지 않으면 프로그램 종료 시 운영 체제에서 회수할 수 있습니다.

#include <stdio.h>
char *getMem(int num)
{
	char *p1 = NULL;
	p1 = (char *)malloc(sizeof(char) * num);
	if (p1 == NULL)
	{
		return NULL;
	}
	return p1;
}
void main()
{
	char *tmp = NULL;
	tmp = getMem(10);
	if (tmp == NULL)
	{
		return ;
	}
	strcpy(tmp, "111222"); //向tmp做指向的内存空间中copy数据,注意不是向指针变量tmp中
	printf("tmp:%s\n", tmp);//输出tmp:111222
	system("pause");
	return ;
}

메모리 분석:

        

 

  • 힙 영역은 由低到高메모리 주소 방향으로 증가하며 그 크기는 시스템 메모리/가상 메모리의 상한선에 의해 결정되며 속도는 느리지만 자유도가 높고 사용 가능한 공간이 큽니다.

힙 영역의 메모리를 동적으로 적용 및 해제
의 기능을 사용하여 동적 메모리 분배를 실현합니다.malloc()free()

void *malloc(size_t);
  • 매개변수 size_t는 할당 크기(바이트)입니다.
  • 반환 값은 void*할당된 공간의 첫 번째 주소를 가리키는 유형 포인터 입니다
    ( void *유형 포인터는 다른 유형의 포인터로 변환될 수 있음).

함수를 사용하여 메모리를 해제하십시오. 그렇지 않으면 메모리 누수가free() 발생합니다 .

void free(void * /*ptr*/);
  • 매개변수는 ptr할당된 메모리의 첫 번째 주소입니다.
  • 반환 값이 없습니다.

평신도의 관점에서:

프로그래머에 의한 수동 적용 및 해제
예: int p=(int )malloc(sizeof(int)10), 이는 40바이트 힙 공간이 적용되었음을 의미하며 적용 후 무료로 해제해야 함을 기억하십시오.
코드 영역은 바이너리 저장소로 변환되는 코드를 저장하는 데 사용됩니다.

1.2.3 (글로벌) 정적 영역

일반적으로 컴파일 시 저장 크기가 결정될 수 있는 변수의 저장 영역에 사용되지만 전체 프로그램 실행 시간 동안 표시되는 全局变量합계 에 사용됩니다 静态变量.
전역 영역은  및  , 로 구성됩니다 . .bss段.data段可读可写

#include <stdio.h>
char * getStr1()
{
	char *p1 = "abcd";
	return p1;
}
char *getStr2()
{
	char *p2 = "abcd";
	return p2;
}
 
void main()
{
	char *p1 = NULL;
	char *p2 = NULL;
	p1 = getStr1();
	p2 = getStr2();
 
	//打印p1 p2 所指向内存空间的数据,不是p1 p2中的数据
	printf("p1:%s , p2:%s \n", p1, p2);//输出p1:abcd , p2:abcd
 
	//打印p1 p2 的值
	printf("p1:%d , p2:%d \n", p1, p2);//输出p1:19184372 , p2:19184372
 
	system("pause");
	return;
}

메모리 분석:

         

 

  • .bss段
    초기화되지 않은 전역 변수와 초기화되지 않은 정적 변수는 .bss 섹션에 저장됩니다.
    0으로 초기화된 전역 변수와 0으로 초기화된 정적 변수는 .bss 섹션에 저장됩니다.
    .bss 세그먼트는 실행 가능한 공간을 차지하지 않으며 해당 내용은 운영 체제에 의해 초기화됩니다.
  • .data段
    초기화된 전역 변수는 .data 세그먼트에 저장됩니다.
    초기화된 정적 변수는 .data 세그먼트에 저장됩니다.
    .data 세그먼트는 실행 파일의 공간을 차지하며 해당 내용은 프로그램에 의해 초기화됩니다.

평신도의 관점에서:

글로벌 영역은 다소 특수한 영역으로 글로벌 변수 영역, 정적 변수 영역, 상수 영역으로 나뉩니다. 전역 변수 영역은 전역 변수를 저장하고, 정적 변수 영역은 변수를 정적으로 수정(정적 로컬 변수, 정적 전역 변수 포함)하여 저장하는데, 이 영역은 정적을 포함하는 한 존재합니다. 상수 영역은 문자 상수와 const에 의해 수정된 전역 변수를 저장하는 데 사용되며 const에 의해 수정된 지역 변수는 여기에 존재하지 않으므로 혼동하지 마십시오. 전역 영역에 저장된 모든 것은 운영 체제에서 관리하며 프로그램이 종료되면 운영 체제에서 해제됩니다. 상수 영역에 저장된 데이터는 포인터를 사용해도 변경할 수 없습니다.const로 수정된 지역 변수는 포인터로 변경할 수 있다고 말할 수 있지만 지역 변수는 상수 영역에 저장되지 않습니다.

1.2.4 상수 면적

字符串,数字 기타 상수는 상수 영역에 저장됩니다.
const변경된 글로벌 변수는 상수 영역에 저장됩니다.
프로그램 실행 중에는 상수 영역의 내용을 수정할 수 없습니다.

1.2.5 코드 영역

程序执行代码코드 영역에 저장되며 값을 수정할 수 없습니다(수정할 경우 오류 발생). 코드 영역에 저장될 수도 있습니다
字符串常量.define定义的常量

        위의 5개 영역인 코드 영역과 전역 영역은 .exe 파일이 생성된 후 생성되며, .exe 파일을 더블 클릭하면 프로그램이 실행되어 스택 영역과 힙 영역이 생성됩니다.
아래 그림 바로 위:

#include<stdio.h>
#include<string.h>
int a = 10;
static int b = 20;
void fun(int x)
{
	char *p = "Hello";
	printf("形参x的地址=%d\n\n", &x);
	printf("Hello的地址=%d\n\n", "Hello");
	printf("指针变量p的地址=%d\n\n", &p);
	return;
}
int main(int argc,const char *argv[])
{
	int c = 10;
	int d = 20;
	static int e = 30;
	char *p = "Hello";
	printf("\n全局变量a的地址=%d\n\n", &a);
	printf("静态全局变量b的地址=%d\n\n", &b);
	printf("静态局部变量e的地址=%d\n\n", &e);
	printf("字符串\"Hello\"的地址=%d\n\n", "Hello");
	printf("局部变量c的地址=%d\n\n", &c);
	printf("局部变量d的地址=%d\n\n", &d);
	printf("指针变量p的地址=%d\n\n", &p);
	fun(5);
	system("pause");
	return 0;
}

 다이어그램을 사용하여 보여주고 요약하면 됩니다.
전역 영역은 전역 변수, 정적 변수, 문자 상수 및 const 수정 전역 변수를 저장합니다. 스택 영역은 로컬 변수 및 함수의 공식 매개 변수와 일부 코드의 주소를 저장합니다. 스택 영역의 내용은 수정할 수 있습니다. 힙 영역은 프로그래머가 수동으로 적용하고 해제합니다. malloc 함수에 의해 적용되고 자유 함수에 의해 해제됩니다
.

만들기가 쉽지 않은데 이 블로그가 도움이 되셨다면 댓글 + 좋아요 부탁드립니다.

추천

출처blog.csdn.net/m0_73381672/article/details/131726780