전제 조건 : 분류 메모리
C / C ++ 프로그램 메모리는 두 가지 범주로 나누어 점령 : 静态存储区
와 动态存储区
. 어떤 모드는 다음과 같습니다 :
정적 메모리, 동적 메모리에 저장된 데이터 사이의 차이이다 정적 기억 영역 编译-链接
, 단계가 식별 된 프로그램이 변경되지 실행되고, 프로그램이 종료는, 상기 메모리는 정적 기억 영역 회수 시스템 일 것이다 때만. 동적 메모리는 프로그램 동작시에 동적으로 할당된다.
다른 장소에서 우리는 글로벌 데이터 영역과 같은 단어 불변 영역으로서 모든 세그먼트의 다른 메모리 할당 분류, 구분이 있음을 알 수 있으며, 속성 분류하는 정적 메모리이다.
메모리의 분류에 여기에 단지 대략 노트 과거 볼 수있는 메모리의 내용에 대한 자세한 상세하게 설명 :
예 : 리턴 포인터가 스택 메모리에 대한 포인터를 반환
복귀를 봐 예제의 스택 메모리 포인터 포인트를 반환합니다 :
#include <stdio.h>
char *GetStr(void)
{
char p[] = "Hello"; /* 保存在栈中 */
return p;
}
int main(void)
{
char *str = NULL;
str = GetStr();
printf("%s\n", str);
return 0;
}
프로그램은 다음과 같이 작업의 결과는, 컴파일 :
당신은 컴파일러 경고를 볼 수 있습니다
경고 : 함수는 지역 변수의 주소를 반환
우리의 운영 결과는 출력 문자열을 기대하지 않습니다 Hello
.
그 때문이다 GetStr
함수, 변수 p는 로컬 변수 스택 메모리에 대한 포인터를 리턴 포인트 및 로컬 변수는 스택에 할당된다. 즉이되는 Hello
결과가 전혀 출력되지 않도록 페이지의 내용이 알려지지 이때 있도록 스택 메모리에 저장되고, 스택 메모리가 자동으로 함수 호출의 끝이 파괴 될 것이다.
송출 GetStr
다음과 같이 함수를 수정 :
char *GetStr(void)
{
char *p = "Hello"; /* p在栈上,Hello在静态区(常量区) */
return p;
}
그 결과는 무엇을이 시간에 실행되도록 컴파일? 그 결과는 다음과 같습니다
당신은 정상 출력을 볼 수 있습니다. 왜 여기 출력 할 수 정상? 여기서 P 스택에 할당하지만, 이번에는 비록 때문에 Hello
정적 메모리에 저장된 문자열 상수이다. 호출에서 GetStr
함수의 끝이 파괴되지 않습니다.
어떤 사람들은 또한, 의심이있을 수 있습니다 Hello
정적 지역에, 왜 스택.
char *p = "Hello";
여기서 제 컴파일러는 스택 포인터 변수 공간을 열 것이다 포인터 변수 (P)를 정의한다. 그리고이 시간을 저장할 수없는 공간에서 Hello
, 그것은 Hello
단지 정적 영역에 저장 될 수있다.
char p[] = "Hello";
어레이 크기가 주어지지 않기 때문에 여기서 P의 첫 번째로 정의 된 어레이는, 어레이의 크기는 현재 결정되지 않는다. 그리고 Hello
상기 어레이에 저장된 컴파일러 배열 P 개구 및 저장에 적합한 스택 공간을 폐쇄 할 것이다 Hello
.
관련 참고 사항 : [노트] C 언어의 char * str을 문자열 str [] 차이를 숯불하기
다른 대안
위의 예에서 우리는 함수가 스택 메모리에 대한 포인터에 대한 포인터를 반환하는 경우, 얻어진 결과는 우리가 원하지 않는 무엇 것을 알고있다. 위의 방법 외에도, 여기서 몇 가지 솔루션이 있습니다 :
글로벌 변수는 정적 메모리 영역에 저장되어 있기 때문에도 1에 도시 된 바와 같이, P는 전역 변수로서 정의되고, 프로그램 방출을 종료한다. 그러나,이 함수가 재진입하지 않습니다됩니다. 재입국 및 재입국의 기능은 기간에 메모를 볼 수 없습니다.
2 GetStr
기능을 사용하여 malloc
동적 메모리를 적용 할 수 있지만, 우리가 사용하는 사용하는 기억해야 free
출시 될, 그렇지 않으면 메모리 누수로 이어질 것입니다. 다음 샘플 코드는 다음과 같습니다
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *GetStr(void)
{
char *p = (char*)malloc(64*sizeof(char));
strcpy(p, "Hello");
return p;
}
int main(void)
{
char *str = NULL;
str = GetStr();
printf("%s\n", str);
free(str); /* 释放str指向的堆内存 */
return 0;
}
도 3에서, P는 정적 변수 정적 변수로 선언 될 수있다. 그러나 그것은 또한 함수가 재진입하지 않습니다됩니다. 다음 샘플 코드는 다음과 같습니다
char *GetStr(void)
{
static char p[] = "Hello";
return p;
}
이들은 잘못된 경우 지적 바랍니다 공유하는이 메모의 내용입니다!
내 개인 블로그 : https://zhengnianli.github.io/
내 마이크로 채널 대중 번호 : 임베디드 엉망진창