C의 함수에 전달된 포인터를 수정하려면 어떻게 해야 하나요?
구조체 목록에 구조체를 추가하는 다음과 같은 코드가 있습니다.
void barPush(BarList * list,Bar * bar)
{
// if there is no move to add, then we are done
if (bar == NULL) return;//EMPTY_LIST;
// allocate space for the new node
BarList * newNode = malloc(sizeof(BarList));
// assign the right values
newNode->val = bar;
newNode->nextBar = list;
// and set list to be equal to the new head of the list
list = newNode; // This line works, but list only changes inside of this function
}
이러한 구조는 다음과 같이 정의됩니다.
typedef struct Bar
{
// this isn't too important
} Bar;
#define EMPTY_LIST NULL
typedef struct BarList
{
Bar * val;
struct BarList * nextBar;
} BarList;
그리고 다른 파일에서 다음과 같은 작업을 수행합니다.
BarList * l;
l = EMPTY_LIST;
barPush(l,&b1); // b1 and b2 are just Bar's
barPush(l,&b2);
그러나 이 후에도 여전히 empty_LIST를 가리키고 있으며, barPush 내부에 작성된 수정 버전이 아닙니다.수정하려면 포인터에 대한 포인터로 목록을 전달해야 합니까? 아니면 다른 다크 주문이 필요합니까?
이렇게 하려면 포인터를 포인터에 전달해야 합니다.
void barPush(BarList ** list,Bar * bar)
{
if (list == NULL) return; // need to pass in the pointer to your pointer to your list.
// if there is no move to add, then we are done
if (bar == NULL) return;
// allocate space for the new node
BarList * newNode = malloc(sizeof(BarList));
// assign the right values
newNode->val = bar;
newNode->nextBar = *list;
// and set the contents of the pointer to the pointer to the head of the list
// (ie: the pointer the the head of the list) to the new node.
*list = newNode;
}
그런 다음 다음과 같이 사용합니다.
BarList * l;
l = EMPTY_LIST;
barPush(&l,&b1); // b1 and b2 are just Bar's
barPush(&l,&b2);
Jonathan Leffler는 코멘트에서 새로운 리스트의 선두를 반환할 것을 제안했습니다.
BarList *barPush(BarList *list,Bar *bar)
{
// if there is no move to add, then we are done - return unmodified list.
if (bar == NULL) return list;
// allocate space for the new node
BarList * newNode = malloc(sizeof(BarList));
// assign the right values
newNode->val = bar;
newNode->nextBar = list;
// return the new head of the list.
return newNode;
}
용도:
BarList * l;
l = EMPTY_LIST;
l = barPush(l,&b1); // b1 and b2 are just Bar's
l = barPush(l,&b2);
일반적인 답변: 변경할 항목에 포인터를 전달합니다.
이 경우 변경할 포인터에 대한 포인터가 됩니다.
C에서는 Everything은 값으로 전달됩니다.
포인터를 이렇게 포인터에 건네줍니다.
int myFunction(int** param1, int** param2) {
// now I can change the ACTUAL pointer - kind of like passing a pointer by reference
}
이것은 전형적인 문제입니다.할당된 노드를 반환하거나 포인터의 포인터를 사용합니다.C에서는 X에 대한 포인터를 X를 수정할 함수에 전달해야 합니다.이 경우 포인터를 수정해야 하므로 포인터에 포인터를 전달해야 합니다.
네, 포인터를 포인터에 넘겨야 합니다.C는 인수를 참조가 아닌 값으로 전달합니다.
다른 함수에서 포인터를 수정하려면 다중 간접이라는 개념이 필요합니다.이것에 대해서는 나중에 설명하겠습니다.@geofftnz의 스포일러 솔루션은 다중 간접을 사용합니다.제가 하려고 하는 것은 C에서 여러 개의 인터다이렉션을 설명하도록 최선을 다하는 것입니다.
다음 두 가지 프로그램을 고려해 보십시오. 코드를 살펴보겠습니다.
다음 프로그램은 여러 개의 인터렉션을 사용하지 않으므로 실패합니다.
오류가 있는 프로그램:
// filename: noIndirection.c
#include <stdio.h>
#include <stdlib.h>
void allocater(int *ptrTempAllctr)
{
ptrTempAllctr = malloc(sizeof(int));
if (ptrTempAllctr == NULL) {
perror("in allocater() memory allocation error");
exit(EXIT_FAILURE);
}
}
int main()
{
int *ptrMain = NULL;
allocater(ptrMain);
if (ptrMain == NULL) {
printf("ptrMain is points to NULL\n");
return 1;
}
//free(ptrMain); // we don't have to free because it will be invalid free.
return 0;
}
의 계획을noIndirection.c
)가 ptrMain
int을 입니다.함수에 전달된 경우 함수의 인수는 임시 변수이므로 함수 범위(본문)에서 임시 포인터 변수가 생성되며 범위를 벗어나면 삭제됩니다.
변수 " " " "ptrTempAllctr
는 발신자가 무엇을 가리키는지(((인수)를 ).main
).ptrMain
은 (를 가리키고 있다)NULL
는 함수에 인수로서 전달되었을 때를 가리킵니다.
를 사용하는 malloc()
에 다른 할 수도 있습니다.ptrTempAllctr
후, 「」, 「」의 를.main
" " " " " " " " " " ( 함수 ( )에 전달되었습니다allocater()
같은 있다(즉, 같은 데이터를 가리키고 있습니다.NULL
이 명령어는 함수 호출 전에 지정되었습니다.
착신했을 때( 「」 「」 「」allocater()
되지 않은 누수가 함수는 범위를 벗어납니다.일시 포인터 변수가 스택에서 팝업되고 메모리가 할당되지 않은 상태로 남아 메모리 누수가 발생합니다.이 제한을 회피하려면 여러 개의 간접방향을 사용해야 합니다.
다중 간접:
Multiple indirection when we use of pointer/s to pointer/s in varying level(with multiple `*`) eg: `int **pp, int ***ppp`, etc.
Address-of(Address-of(주소))를 사용하여 합니다.&
).
여러 개의 간접 포인터 유형 변수가 하는 것은 위의 프로그램을 수정하기 위한 포인터 변수 자체에 대한 포인터입니다. 하면 ''를 전달할 수 .ptrMain
로로 합니다.allocater()
, 이 콜의
allocater(&ptrMain);
때문에, 의 프로그램 「 」은, 「 」를 참조해 주세요.noIndirection.c
안 프로그램 .이치노withIndirection.c
을 하다
int 포인터에 대한 포인터가 필요합니다.int **ptrMain
의 함수 로서 「」를 지정합니다.allocater()
(noDirection.c)로 설정합니다.
이것은 다음 프로그램에서 사용되었습니다.
다음 프로그램에서는 이전 프로그램의 버그를 해결하기 위해 여러 개의 인터렉션을 사용하고 있습니다.
// filename: withIndirection.c
#include <stdio.h>
#include <stdlib.h>
void trueAllocater(int **ptrTrueAllocater)
{
*ptrTrueAllocater = (int *) malloc(sizeof(int));
if (ptrTrueAllocater == NULL) {
perror("in trueAllocater() memory allocation error");
exit(EXIT_FAILURE);
}
}
int main(void)
{
int *ptrMain = NULL;
trueAllocater(&ptrMain);
if (ptrMain == NULL) {
printf("memory not allocated\n");
return EXIT_FAILURE;
}
printf("memory allocated and assigned to ptrMain");
printf(" from trueAllocater\n");
free(ptrMain);
return EXIT_SUCCESS;
}
를 보다withIndirection.c
참고하도록 하겠습니다.
변수 .ptrMain
)trueAllocater(&ptrMain);
change) trueAllocator로 ptrMain
에 trueAllocater()
또는 다른 함수를 사용하려면 이 함수는 전달된 변수에 대한 현재 이해에 인수 선언에 추가된 다른 *를 추가하는 올바른 수준의 간접 포인터를 받아들여야 합니다.
수단까지 우리는 수단과통해 우리는 방법을 필요가 있다.trueAllocater()
로서 기능하다로 기능 논쟁int **
부터에서int *
에에withIndirection.c
로 와는 반대로에 반대하noIndirection.c
그래서 간접 참조 수준 statisfied 것이다.그 때문에,간접레벨이 통계화 됩니다.
변수의 가 「」인 경우.ptrMain
임시변통ptrTrueAllocater
변수 ""의 .ptrMain
발신자 주소)main
는 어떤 변수가 아니라 합니다.ptrMain
은 (실제)NULL
(하고 있다을 가리키다).main
를 참조해 주세요.
「 」를 참조 하면,ptrTrueAllocater
를 변경하다ptrMain
예요.왜냐하면ptrTrueAllocater
를 가리킵니다.main
ptrMain
그 내용이 아니라 변수 자체입니다.
되지 않은 ptrTrueAllocater
입니다(「」).main
의 variable의 variable()은 (으)로 표시됩니다.ptrMain
최종 데이터를 얻으려면 참조를 1개 더 해야 합니다.
한 번 를 해제해야 를 알 수 있습니다.ptrMain
를 하고, 「」 「 」 「 」 「 」ptrMain
번 .ptrMain
, 「」입니다.NULL
.
@PaulWicks 변경하려고 했으므로 포인팅 위치를 할당하거나 변경하려면 참조를 한 번 취소해야 합니다.
포인터를 사용하는 다중 간접의 목적은 포인터가 필요한 다차원 배열을 만들고 포인터 인수를 전달하는 것입니다.
다음과 같이 조작해야 하는 유형에 따라 변수를 변경해야 합니다.
선언에 *를 추가할 때마다 포인터 간접 레벨이 증가하며 참조 해제될 때마다 데이터에 근접하는 포인터 간접 레벨이 감소합니다.
이 문제는 필요한 포인터 변수에 할당되어 있는 발신자 함수에 주소를 되돌리는 것으로 해결할 수 있습니다.
네, 이 다중 간접 변수 구문을 사용하여 1차원 또는 다차원 배열을 만들 수 있습니다.이것은 처음에 초보자들을 혼란스럽게 할 것이다.만약 그들이 많은 코드를 읽을 시간을 둔다면 그들은 그들 사이의 차이를 찾을 수 있을 것이다.
제가 틀렸다면 정정해주시고, 피드백과 여러 간접 포인터의 다른 사용법을 알려주세요.제가 영어를 잘못해서 죄송합니다.여러 가지 지시사항을 이해하는 데 도움이 되는 자료입니다.https://boredzo.org/pointers/ #function_http://rt_lt.rule.http://https://cseweb.ucsd.edu/
언급URL : https://stackoverflow.com/questions/766893/how-do-i-modify-a-pointer-that-has-been-passed-into-a-function-in-c
'programing' 카테고리의 다른 글
Linux에서 인터페이스의 IP 주소를 가져옵니다. (0) | 2022.06.18 |
---|---|
C 프리프로세서: #warning으로 매크로를 전개합니다. (0) | 2022.06.18 |
Vuex가 복잡한 개체에 반응하지 않음 (0) | 2022.06.18 |
Java에서는 (a==1 & a==2 & a==3)가 true로 평가될 수 있습니까? (0) | 2022.06.18 |
Postman에서 파일 및 JSON 데이터를 업로드하려면 어떻게 해야 합니까? (0) | 2022.06.18 |