Programing

내 변수는 C에 저장되어 있는 메모리 내의 위치

c10106 2022. 5. 16. 20:54
반응형

내 변수는 C에 저장되어 있는 메모리 내의 위치

메모리가 데이터, 힙, 스택, 코드 등 4개 세그먼트로 나뉘는 것을 고려해 글로벌 변수, 정적 변수, 상수 데이터 유형, 로컬 변수(함수에 정의 및 선언), 변수(주함수), 포인터, 동적으로 할당된 공간(몰록 및 콜록 사용)은 메모리에 저장되는 곳이 어디인가?

나는 그들이 다음과 같이 할당될 것이라고 생각한다.

  • 전역 변수 ------> 데이터
  • 정적 변수 ------> 데이터
  • 상수 데이터 유형 ----> 코드
  • 로컬 변수(함수에 선언 및 정의됨) --------> 스택
  • 주함수에 선언되고 정의된 변수 ----> 힙
  • 포人인:char *arrint *arr 힙) ------->
  • 동적으로 할당된 공간(Malloc 및 Calloc 사용) --------> 스택

나는 C의 관점에서만 이 변수들을 언급하고 있다.

C는 처음이라 틀렸다면 고쳐줘.

자네에겐 이런 권리가 있지만 누가 질문을 썼든 적어도 한 가지 질문에 대해 속였다네

  • 전역 변수 ------> 데이터(수정)
  • 정적 변수 ------> 데이터(수정)
  • 상수 데이터 유형 ----> 코드 및/또는 데이터.상수 자체가 데이터 세그먼트에 저장되고 그에 대한 참조가 코드에 포함된 경우 문자열 리터럴을 고려하십시오.
  • 국소 변수(함수에 정의 및 정의됨) -------> 스택(수정)
  • 에 선언되고 정의된 변수main함수 ----> 산더미처럼 쌓다 또한 쌓는다(선생님이 당신을 속이려 했다)
  • 포인터(예:char *arrint *arr) -------> 산더미처럼 쌓다 컨텍스트에 따라 데이터 또는 스택.C는 글로벌 또는 글로벌을 선언할 수 있도록 한다.static포인터, 이 경우 포인터 자체가 데이터 세그먼트에 있게 된다.
  • 동적으로 할당된 공간(사용)malloccallocrealloc) --------> 쌓다 산더미처럼 쌓다

"스택"을 공식적으로 "자동 스토리지 클래스"라고 부르는 것은 언급할 가치가 있다.

이러한 메모리 세그먼트에 대해 알고 싶어할 수 있는 미래 방문자들을 위해, 나는 C:에 5개의 메모리 세그먼트에 대한 중요한 포인트를 쓰고 있다.

일부 주의 사항:

  1. C 프로그램이 실행될 때마다 일부 메모리는 프로그램 실행을 위해 RAM에 할당된다.이 메모리는 자주 실행되는 코드(이진 데이터), 프로그램 변수 등을 저장하는 데 사용된다.아래의 메모리 부분은 다음과 같다.
  2. 일반적으로 세 가지 유형의 변수가 있다.
    • 국부 변수(C에서는 자동 변수라고도 함)
    • 전역 변수
    • 정적 변수
    • 글로벌 정적 또는 로컬 정적 변수를 가질 수 있지만 위의 세 가지가 상위 유형이다.

C의 메모리 세그먼트 5개:

1. 코드 세그먼트

  • 텍스트 세그먼트라고도 하는 코드 세그먼트는 자주 실행되는 코드를 포함하는 메모리 영역이다.
  • 코드 세그먼트는 버퍼 오버플로 등과 같은 프로그래밍 버그에 의해 오버라이드되는 위험을 피하기 위해 읽기 전용인 경우가 많다.
  • 코드 세그먼트는 로컬 변수(C에서는 자동 변수라고도 함), 전역 변수 등과 같은 프로그램 변수를 포함하지 않는다.
  • C 구현에 기초하여 코드 세그먼트는 읽기 전용 문자열 리터럴도 포함할 수 있다.를 들어,이 를를 할 때, 때 때.printf("Hello, world")그러면 코드/텍스트 세그먼트에 "Hello, world" 문자열이 생성된다.다음을 사용하여 이를 확인할 수 있다.sizeLinux OS에서 명령.
  • 추가 읽기

데이터 세그먼트

데이터 세그먼트는 아래 두 부분으로 나뉘며 일반적으로 힙 영역 아래 또는 스택 위의 일부 구현에 위치하지만, 데이터 세그먼트는 힙 영역과 스택 영역 사이에 위치하지 않는다.

2. 초기화되지 않은 데이터 세그먼트

  • 이 세그먼트는 bss로도 알려져 있다.
  • 이 부분은 다음을 포함하는 메모리의 부분이다.
    1. 초기화되지 않은 전역 변수 (포인터 변수 포함)
    2. 초기화되지 않은 상수 전역 변수.
    3. 초기화되지 않은 로컬 정적 변수.
  • 초기화되지 않은 전역 또는 정적 로컬 변수는 초기화되지 않은 데이터 세그먼트에 저장됨
  • 예: 전역 수 있음int globalVar;또는 정적 로컬 변수static int localStatic;초기화되지 않은 데이터 세그먼트에 저장될 것이다.
  • 글로벌 변수를 선언하고 초기화하는 경우0또는NULL초기화되지 않은 데이터 세그먼트 또는 bss로 이동한다.
  • 추가 읽기

3. 초기화 데이터 세그먼트

  • 이 세그먼트는 다음을 저장한다.
    1. 초기화된 전역 변수 (포인터 변수 포함)
    2. 초기화된 상수 전역 변수.
    3. 초기화된 로컬 정적 변수.
  • 예: 전역 수 있음int globalVar = 1;또는 정적 로컬 변수static int localStatic = 1;초기화된 데이터 세그먼트에 저장된다.
  • 이 세그먼트는 초기화된 읽기 전용 영역과 초기화된 읽기-쓰기 영역으로 추가로 분류할 수 있다.초기화된 상수 전역 변수는 초기화된 읽기 전용 영역으로 이동하며, 런타임에 값을 수정할 수 있는 변수는 초기화된 읽기-쓰기 영역으로 이동한다.
  • 이 세그먼트의 크기는 프로그램의 소스 코드에 있는 값의 크기에 따라 결정되며 런타임변경되지 않는다.
  • 추가 읽기

4. 쌓기 세그먼트

  • 스택 세그먼트는 내부 함수(함수가 주 함수 또는 사용자 정의 함수가 될 수 있음)에서 생성되는 변수를 저장하는 데 사용된다.
    1. 함수의 로컬 변수(포인터 변수 포함)
    2. 기능에 전달된 인수
    3. 반송 주소
  • 스택에 저장된 변수는 기능 실행이 완료되는 즉시 제거된다.
  • 추가 읽기

5. 힙 세그먼트

  • 이 세그먼트는 동적 메모리 할당을 지원하는 것이다.만약 프로그래머가 약간의 메모리를 동적으로 할당하기를 원한다면 C에서는 를 사용하여 수행된다.malloccalloc또는realloc방법들
  • 예를 들어, 다음과 같은 경우int* prt = malloc(sizeof(int) * 2)그러면 8바이트가 힙에 할당되고 해당 위치의 메모리 주소가 반환되어 저장된다.ptr가변의ptr변수는 선언/사용 방식에 따라 스택 또는 데이터 세그먼트에 위치한다.
  • 추가 읽기

틀린 문장은 고쳤다.

constant data types ----->  code //wrong

국부 상수 변수 ----> 스택

초기화된 글로벌 상수 변수 ----> 데이터 세그먼트

초기화되지 않은 글로벌 상수 변수 ----> bss

variables declared and defined in main function  ----->  heap //wrong

주함수에 선언되고 정의된 변수 ----> 스택

pointers(ex:char *arr,int *arr) ------->  heap //wrong

dynamically allocated space(using malloc,calloc) --------> stack //wrong

포인터(예:char *arr,int *arr) -------> 크기의 포인터들이 스택에 있을 것이다.

메모리를 n바이트로 할당하고 있다고 가정하십시오(사용).malloc또는calloc를 동적으로 표시한 다음 포인터 변수를 만든다.이제 그만.n메모리 바이트가 힙에 있고 포인터 변수가 4바이트(64비트 시스템 8바이트인 경우)이며, 이 경우 스택에 저장되어n메모리 청크 바이트

참고: 포인터 변수는 모든 세그먼트의 메모리를 가리킬 수 있다.

int x = 10;
void func()
{
int a = 0;
int *p = &a: //Now its pointing the memory of stack
int *p2 = &x; //Now its pointing the memory of data segment
chat *name = "ashok" //Now its pointing the constant string literal 
                     //which is actually present in text segment.
char *name2 = malloc(10); //Now its pointing memory in heap
...
}

동적으로 할당된 공간(malloc,calloc 사용) ---------> 힙

인기 있는 데스크톱 아키텍처는 프로세스의 가상 메모리를 여러 세그먼트로 나눈다.

  • 텍스트 세그먼트: 실행 코드 포함.명령 포인터는 이 범위의 값을 취한다.

  • 데이터 세그먼트: 전역 변수(즉, 정적 연결이 있는 개체) 포함.읽기 전용 데이터(예: 문자열 상수)와 초기화되지 않은 데이터("BSS")로 세분화됨.

  • 스택 세그먼트: 프로그램에 대한 동적 메모리(예: 자유 저장소("Heap")와 모든 스레드에 대한 로컬 스택 프레임이 들어 있다.전통적으로 C 스택과 C 힙은 반대편 끝에서 스택 세그먼트로 성장했지만, 나는 연습이 너무 안전하지 않기 때문에 포기되었다고 믿는다.

C 프로그램은 일반적으로 정적 스토리지 기간이 있는 객체를 데이터 세그먼트에 배치하고, 자유 저장소에 동적으로 할당된 객체, 그리고 자동 객체를 자신이 살고 있는 스레드의 호출 스택에 배치한다.

이전 x86 리얼 모드나 임베디드 장치와 같은 다른 플랫폼에서는 분명히 사물이 근본적으로 다를 수 있다.

스토리지에 대해 명심해야 할 한 가지 사항은 "있는 그대로의 규칙"이다.컴파일러는 변수를 특정 장소에 둘 필요가 없다. 대신 컴파일러가 컴파일된 프로그램이 추상 C 기계의 규칙에 따라 추상 C 기계에서 실행된 처럼 동작하는 한 원하는 곳에 변수를 배치할 수 있다.이는 모든 저장 기간에 적용된다.예를 들면 다음과 같다.

  • 모두 액세스되지 않는 변수는 완전히 제거될 수 있다. 저장소가 없다...어디든예제 - 있는 방법 보기42생성된 조립품 코드에는 있지만 의 흔적은 없다.404.
  • 주소를 사용하지 않는 자동 저장 기간을 가진 변수는 메모리에 전혀 저장할 필요가 없다.예를 들어 루프 변수가 있을 수 있다.
  • 라고 하는 .const또는 효과적으로const기억할 필요가 없다.예제 - 컴파일러가 다음을 증명할 수 있음foo효과적으로const그리고 그것을 코드에 넣는다.bar외부 연결이 있으며 컴파일러는 현재 모듈 외부에서 변경되지 않을 것임을 증명할 수 없으므로 인라인 처리되지 않는다.
  • 사사에 된 malloc힙에서 할당된 메모리에 상주할 필요가 없음! - 코드에 호출이 없는 방법 확인malloc그리고 42라는 값도 기억 속에 저장되어 있지 않다. 그것은 기록부에 보관되어 있다!
  • 라라고 물체는 는malloc그리고 참조는 다음 구성 요소와 함께 객체를 할당하지 않고 손실된다.free 기억을 흘릴 필요가 없다...
  • 에 의해 할당된 목적malloc프로그램 중단 아래의 힙 안에 있을 필요는 없음(sbrk(0)Unixen에서...

나는 C의 관점에서만 이 변수들을 언급하고 있다.

C 언어의 관점에서, 중요한 것은 범위, 범위, 연결 및 접근이다; 정확히 어떻게 항목이 다른 메모리 세그먼트에 매핑되는가는 개별 구현에 달려있다. 그리고 그것은 다양할 것이다.언어 표준은 기억력에 대해 전혀 이야기하지 않는다.대부분의 최신 아키텍처들은 거의 같은 방식으로 작용한다; 블록 범위 변수와 함수 인수는 스택에서 할당될 것이다, 파일 범위와 정적 변수는 데이터 또는 코드 세그먼트에서 할당될 것이다, 동적 메모리는 힙에서 할당될 것이다, 일부 상수 데이터는 읽기 전용 세그먼트에 저장될 것이다.

분해 분석을 통한 Linux 최소 실행 가능 예

표준에 명시되지 않은 구현 세부사항이므로 컴파일러가 특정 구현에 대해 어떤 작업을 수행하고 있는지 살펴보도록 하자.

이 답변에서 분석을 수행하는 구체적인 답변에 링크하거나, 여기서 직접 분석을 제공하고, 여기에 모든 결과를 정리하겠다.

이 모든 것들이 다양한 Ubuntu / GCC 버전에 있고, 그 결과는 버전에 걸쳐 상당히 안정적일 것 같지만, 만약 우리가 어떤 변형을 발견한다면 좀더 정확한 버전을 명시하자.

함수 내부의 로컬 변수

Be Itmain또는 다른 기능:

void f(void) {
    int my_local_var;
}

과 같이: gdb에서 < 최적화 아웃>무엇을 의미하는가?

  • -O0: 쌓다
  • -O3: 흘리지 않으면 등록하고, 그렇지 않으면 쌓는다.

스택이 존재하는 이유에 대한 동기는 다음을 참조하십시오.x86 어셈블리의 레지스터에 사용되는 푸시/팝 명령의 기능은 무엇인가?

및 전역 수 있다.static 가능

/* BSS */
int my_global_implicit;
int my_global_implicit_explicit_0 = 0;

/* DATA */
int my_global_implicit_explicit_1 = 1;

void f(void) {
    /* BSS */
    static int my_static_local_var_implicit;
    static int my_static_local_var_explicit_0 = 0;

    /* DATA */
    static int my_static_local_var_explicit_1 = 1;
}

char *그리고char c[]

에서와 같이: C와 C++에 정적 변수가 저장되어 있는 위치는?

void f(void) {
    /* RODATA / TEXT */
    char *a = "abc";

    /* Stack. */
    char b[] = "abc";
    char c[] = {'a', 'b', 'c', '\0'};
}

TODO는 또한 매우 큰 문자열 리터럴을 스택에 넣을 것인가?아니면.data아니면 컴파일이 실패하는가?

함수 인수

void f(int i, int j);

관련 전화 회의를 거쳐야 한다. 예:각 변수에 대한 특정 레지스터 또는 스택 위치를 지정하는 X86용 https://en.wikipedia.org/wiki/X86_calling_conventions.

그렇다면 gdb에서 < 최적화 아웃>의미하는 바는 무엇인가?-O0그리고 나서 모든 것을 스택에 집어넣는다.-O3가능한 한 많은 레지스터를 사용하려고 한다.

하지만 이 기능이 삽입되면 일반 현지인과 똑같이 취급된다.

const

나는 네가 그것을 타이프로 보낼 수 있기 때문에 그것이 아무런 차이가 없다고 믿는다.

반대로, 컴파일러가 어떤 데이터는 절대 작성되지 않는다고 판단할 수 있다면, 이론상으로는 그것을 에 배치할 수 있다..rodata비록 경솔하지는 않더라도

TODO 분석.

포인터

변수(주소 포함, 숫자)로, 나머지 모든 변수 :-)

만록의

그 문제는 그다지 타당하지 않다.malloc그 이후malloc함수로서, 다음에서:

int *i = malloc(sizeof(int));

*i주소가 포함된 변수여서 위의 경우에 해당된다.

malloc가 내부적으로 작동하는 방식에 대해서는, 당신이 그것을 리눅스 커널이라고 부르면, 그것의 내부 데이터 구조에서 쓰기 가능한 것으로 특정 주소를 표시하고, 그것들이 처음에 프로그램에 의해 터치되면, 결함이 발생하고 커널이 페이지 테이블을 가능하게 하여, segfaul 없이도 액세스가 가능하도록 한다.x86 페이징은 어떻게 작동하는가?

단, 이는 기본적으로 다음과 같은 사항이라는 점에 유의하십시오.exec실행 파일을 실행하려고 할 때 syscall은 로드할 페이지를 표시하고 프로그램을 여기에 쓰는 등의 작업을 후드 아래에서 수행한다(참조).커널이 실행 가능한 이진 파일을 Linux에서 실행하는 방법은?그것만 빼면exec로딩할 위치에 대한 몇 가지 추가적인 제한이 있음(예: 코드를 다시 연결할 수 없는 경우).

ㅇㅇ에 은 한국 syscallmalloc이다mmap현대적인 2020년 구현에서 그리고 과거에brk사용된 항목:malloc()는 brk() 또는 mmap()를 사용하는가?

동적 라이브러리

기본적으로 얻는다mmaped to memory: https://unix.stackexchange.com/questions/226524/what-system-call-is-used-to-load-libraries-in-linux/462710#462710

와 환경 수 있다.mainargv

초기 스택 이상: https://unix.stackexchange.com/questions/75939/where-is-the-environment-string-actual-stored TODO .data에서는 왜 안 되는가?

  • 변수/자동 변수 ---> 스택 섹션
  • 동적으로 할당된 변수 ---> 힙 섹션
  • 초기화 전역 변수 -> 데이터 섹션
  • 초기화되지 않은 전역 변수 -> 데이터 섹션(bss)
  • 정적 변수 -> 데이터 섹션
  • 문자열 상수 -> 텍스트 섹션/코드 섹션
  • 기능 -> 텍스트 섹션/코드 섹션
  • 텍스트 코드 -> 텍스트 섹션/코드 섹션
  • 레지스터 -> CPU 레지스터
  • 명령줄 입력 -> 환경/명령줄 섹션
  • 환경변수 -> 환경/명령줄 섹션

포인터(예:char *arr,int *arr) -------> 힙

아니, 스택에 있을 수도 있고 데이터 세그먼트에 있을 수도 있어.그들은 어디를 가리킬 수 있다.

참조URL: https://stackoverflow.com/questions/14588767/where-in-memory-are-my-variables-stored-in-c

반응형