programing

포인터를 사용하여 다른 함수에서 로컬 변수에 액세스하는 방법

newsource 2022. 8. 16. 23:25

포인터를 사용하여 다른 함수에서 로컬 변수에 액세스하는 방법

다른 기능의 로컬 변수에 액세스할 수 있습니까?만약 그렇다면, 어떻게?

void replaceNumberAndPrint(int array[3]) {
    printf("%i\n", array[1]);
    printf("%i\n", array[1]);
}

int * getArray() {
    int myArray[3] = {4, 65, 23};
    return myArray;
}

int main() {
    replaceNumberAndPrint(getArray());
}

위의 코드 출력:

65
4202656

내가 뭘 잘못하고 있지?"4202656"은 무슨 뜻입니까?

전체를 ?replaceNumberAndPrint()음보보다다다다다?????????

myArray이 「」의 마지막까지).getArray가 남습니다 하다. 하면 정의되지않은 행동이 .나중에 액세스하면 정의되지 않은 동작이 발생합니다.

하는 것은 '콜'이 '콜'이 '콜'하는 입니다.printf.myArray하다

(「 」 「 」 「 」 「 」 「 」 「 」 「 」 「 」 「 」 「 」 。main를 지정하거나 힙에 할당합니다.힙에 할당하는 경우 수동으로 해제하거나 RAII를 사용하여 C++로 해제해야 합니다.

제가 놓친 대안 중 하나는 어레이가 너무 크지 않은 경우에는 어레이를 구조체로 정리하여 값 유형으로 만드는 것입니다.그런 다음 반환하면 함수 반환에서 살아남은 복사본이 생성됩니다.자세한 내용은 tp1답변을 참조하십시오.

로컬 변수가 범위를 벗어나면 해당 변수에 액세스할 수 없습니다.이것이 로컬 변수가 된다는 의미입니다.

에서 하고 replaceNumberAndPrint이치노처음 작동한 것처럼 보이는 것은 그저 운이 좋은 우연의 일치일 뿐이다.은 스택 되지 않은 첫 번째 콜에 되어 있을 이 있습니다만, 은 「」로 설정되어 .printf 이 을 덮어씁니다. 두 으로 넘어갑니다.그번 、 번번2 번printf을 하다

배열 데이터를 힙에 저장하고 포인터를 전달하거나 범위 내에 남아 있는 변수(예: 주 함수 내의 전역 또는 기타)에 전달해야 합니다.

C++ 솔루션:

"다른 기능의 로컬 변수에 액세스할 수 있습니까?그렇다면 어떻게?

정답은 '아니오'입니다.기능이 종료된 후가 아닙니다.로컬 변수는 그 시점에서 파기됩니다.

C++반환되는 어레이를 처리하는 방법은 std::array(표준 크기) 또는 std::array(동적 크기)와 같은 컨테이너에서 어레이를 관리하는 것입니다.

예:

void replaceNumberAndPrint(const std::array<int, 3>& array) {
    printf("%i\n", array[0]);
    printf("%i\n", array[1]);
    printf("%i\n", array[2]);
}

std::array<int, 3> getArray() {
    std::array<int, 3> myArray = {4, 65, 23};
    return myArray;
}

두 번째 함수에서는 반환된 값이 컴파일러에 의해 최적화되므로 실제로 어레이를 복사하는 비용은 들지 않습니다.

그런 거 해봐.'킬'을 하는 방법myArray로컬로 정의되어 있는 경우.

#include <stdio.h>
#include <stdlib.h>

void replaceNumberAndPrint(int * array) {
 printf("%i\n", array[0]);
 printf("%i\n", array[1]);
 printf("%i\n" , array[2]);
 free(array);
}

int * getArray() {
 int * myArray = malloc(sizeof(int) * 3);
 myArray[0] = 4;
 myArray[1] = 64;
 myArray[2] = 23;
 //{4, 65, 23};
 return myArray;
}

int main() {
 replaceNumberAndPrint(getArray());
}

기타 : http://www.cplusplus.com/reference/clibrary/cstdlib/malloc/

편집: 코멘트가 올바르게 지적한 바와 같이, 보다 좋은 방법은 다음과 같습니다.

#include <stdio.h>
#include <stdlib.h>

void replaceNumberAndPrint(int * array) {
    if(!array)
        return;

    printf("%i\n", array[0]);
    printf("%i\n", array[1]);
    printf("%i\n" , array[2]);
}

int * createArray() {
    int * myArray = malloc(sizeof(int) * 3);

    if(!myArray)
        return 0;

    myArray[0] = 4;
    myArray[1] = 64;
    myArray[2] = 23;
    return myArray;
}

int main() {
    int * array = createArray();
    if(array)
    {
        replaceNumberAndPrint(array);
        free(array);
    }
    return 0;
}

getArray를 종료하면 myArray가 범위를 벗어납니다.대신 힙에 공간을 할당해야 합니다.

코드가 정의되지 않은 동작을 호출하는 이유는 다음과 같습니다.myArray즉시 범위를 벗어나다getArray()를 반환하고, 당글링 포인터를 사용(참조 해제)하려고 하면 UB가 됩니다.

로컬 변수는 반환 시 범위를 벗어나므로 로컬 변수에 포인터를 반환할 수 없습니다.

(히프에) 동적으로 할당해야 합니다.malloc또는new. 예:

int *create_array(void) {
    int *array = malloc(3 * sizeof(int));
    assert(array != NULL);
    array[0] = 4;
    array[1] = 65;
    array[2] = 23;
    return array;
 }
 void destroy_array(int *array) {
     free(array);
 }
 int main(int argc, char **argv) {
     int *array = create_array();
     for (size_t i = 0; i < 3; ++i)
         printf("%d\n", array[i]);
     destroy_array(array);
     return 0;
 }

또는 의미론이 다르므로 어레이를 정적으로 선언할 수 있습니다.예:

int *get_array(void) {
    static int array[] = { 4, 65, 23 };
    return array;
 }
 int main(int argc, char **argv) {
     int *array = get_array();
     for (size_t i = 0; i < 3; ++i)
         printf("%d\n", array[i]);
     return 0;
 }

모르는 게 있으면static, 이 문답을 읽어주세요.

올바른 방법은 다음과 같습니다.

struct Arr {
   int array[3];
};
Arr get_array() {
   Arr a;
   a.array[0] = 4;
   a.array[1] = 65;
   a.array[2] = 23;
   return a;
}
int main(int argc, char **argv) {
   Arr a = get_array();
   for(size_t i=0; i<3; i++)
       printf("%d\n", a.array[i]);
   return 0;
}

이 작업을 수행해야 하는 이유를 이해하려면 크기(배열)가 어떻게 작동하는지 알아야 합니다.C(따라서 c++)는 배열을 복사하지 않기 위해 노력하고 있으며, 이를 통과하기 위해서는 구조가 필요합니다.복사가 필요한 이유는 스코프 때문입니다.get_array() 함수의 스코프는 사라지고 그 스코프에서 필요한 모든 값을 호출 스코프로 복사해야 합니다.

이 코드에서는 로컬 개체에 대한 포인터를 사용했지만 함수가 반환되면 모든 로컬 변수가 범위를 벗어납니다.메모리를 할당하는 경우(사용 방법)malloc()할당 기능)을 사용하면 데이터가 손실되거나 덮어쓰지 않습니다.

int* getArray(int size) {
    int *myArray = (int*)malloc(size*sizeof(int));
    myArray[0] = 4;
    myArray[1] = 65;
    myArray[2] = 23;
    return myArray;
}

int main() {
    int i;
    int *vector = getArray(3);
    for(i=0;i<3;i++)
    {
        printf("%i\n",vector[i]);
    }
    getch();
    return 0;
}

이 코드는 모든 어레이 요소를 인쇄하고 덮어쓰기를 수행하지 않습니다.

정적..또는...c 내에서 글로벌하게 하면 효과가 있습니다.

단, 프로그램이 이들 3바이트를 차지하지만 이와 같은 간단한 작업에서는 malloc을 수행하지 않습니다(대형 어레이에서는 malloc을 권장합니다).

반면 외부 함수가 포인터를 수정하면 포인터가 포인터를 가리키기 때문에 내부 'myArray'가 수정됩니다.

int myArray[3];
int * getArray() {
    myArray[0] = 4;
    myArray[1] = 65;
    myArray[2] = 23;
    return myArray;
}

언급URL : https://stackoverflow.com/questions/4570366/how-to-access-a-local-variable-from-a-different-function-using-pointers