오류가 발생하기 쉬운, 고전적인 질문은 : 더 리턴 스택 메모리 포인터의 지점을 반환

전제 조건 : 분류 메모리

C / 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/
내 마이크로 채널 대중 번호 : 임베디드 엉망진창

추천

출처www.cnblogs.com/zhengnian/p/11491110.html