2014-02-20 3 views
3

C FAQ on instantiating a matrix using a double pointer의 조언에 따라 다른 문제가 발생했습니다. 나는이 문제를 해결할 수 있었지만 그것이 왜 일방적으로 작동하는지 이해할 수는 없었습니다.참조로 전달 된 변수 수정과 함수에서 반환하는 변수 수정

I 작동하는 다음 코드를 가지고 있고, 나는 당신에게 작동하지 않는 비트를 표시합니다, 나는 당신이 이유를 설명 할 수 있기를 바랍니다 :

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

int HEIGHT = 20; 
int WIDTH = 20; 

int ** curr_grid; 

/** 
* Generate an array with the given height and length 
*/ 
int ** create_grid() { 
    int ** grid; 
    grid = malloc(sizeof(int *) * HEIGHT); 
    int row; 
    for (row = 0; row < HEIGHT; row++) 
     grid[row] = malloc(sizeof(int) * WIDTH); 
    return grid; 
} 

/* Entry Point main */ 
int main(int argc, char** argv) { 
    curr_grid = create_grid(); 
    curr_grid[0][0] = 0; 
    free(curr_grid); // Release heap resources 
    return 0; 
} 

그리드에 대한 메모리를 할당하고 반환 이 방법으로 포인터가 작동합니다. 그러나, 나는 처음에는 또한 작동합니다 확신했다 또 다른 방법을 시도하지만, 그렇지 않습니다 :

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

int HEIGHT = 20; 
int WIDTH = 20; 

int ** curr_grid; 

/** 
* Generate an array with the given height and length 
*/ 
create_grid(int ** grid) { 
    grid = malloc(sizeof(int *) * HEIGHT); 
    int row; 
    for (row = 0; row < HEIGHT; row++) 
     grid[row] = malloc(sizeof(int) * WIDTH); 
} 

/* Entry Point main */ 
int main(int argc, char** argv) { 
    create_grid(curr_grid); 
    curr_grid[0][0] = 0; // Segmentation Fault 
    free(curr_grid); // Release heap resources 
    return 0; 
} 

이 방법으로 표시된 라인에 세그멘테이션 결함으로 종료하고 있어요. 그러나 참조로 변수를 전달하면 수정할 수 있다는 인상을 받았습니다.

왜 작동하지 않습니까?

+0

함수 내'grid'는'main'에서 전달 된 매개 변수의 ** copy **입니다 ... –

+1

제목에 "passed by reference"가 표시되지만 실제로 수행하지는 않습니다. –

+0

아마도 나는 완전한 C 초보자라는 것을 알 수 있습니다. 질문의 이름을 바꾸는 아이디어가 있다면 매우 감사 할 것입니다. – mydoghasworms

답변

1

이 원하는 :

void create_grid(int ***grid) { 
    *grid = malloc(sizeof(int *) * HEIGHT); 
    int row; 
    for (row = 0; row < HEIGHT; row++) 
     (*grid)[row] = malloc(sizeof(int) * WIDTH); 
} 

/* Entry Point main */ 
int main(int argc, char** argv) { 
    create_grid(&curr_grid); 
    curr_grid[0][0] = 0; 
    free(curr_grid); // Release heap resources 
    return 0; 
} 

그것은 아래의 예처럼 :

int MyFunction() 
{ 
    return 3 ; // we return directly 3 
} 

void main() 
{ 
    int a ; 
    a = MyFunction() ;  
} 

대 :

void MyFunction1(int *pa) 
{ 
    *pa = 3 ; // we assign 3 to the memory location pointed by pa 
} 

void main2() 
{ 
    int a ; 
    MyFunction1(&a) ; // we pass the pointer to a/
    // now a contains 3 
} 
+0

포인터에 포인터를 전달해야한다고 말하는 것입니까? 사실 덕분에 생각했습니다. 포인터이기 때문에 이미 메모리의 공간을 수정할 수 있습니다 – mydoghasworms

+0

예 void 함수를 통해 int를 수정하려는 경우 (위와 같이) 포인터를 'int'에 전달해야합니다. int에 대한 포인터 당신은'int'에 대한 포인터에 포인터를 넘겨야 만합니다. 당신의 경우에는 int ('int ** currgrid')에 대한 포인터에 대한 포인터를 수정하기를 원할 것입니다. 포인터를 가리키는 포인터입니다. 당신이 찾고자하는 바가 있다면 대답을 받아주세요. –

+0

답변이나 const를 받아 들일지 잘 모르겠습니다. 더 나은 설명을 제공해 주었지만 * ** 당신처럼. – mydoghasworms

2

귀하의 여기 create_grid(curr_grid); 을 말함으로써 포인터의 주소를 통과하지 그것의 값을 curr_grid 포인터에 전달 (임의의 값) 그리고 그리드에 그 가치를 가져 가라. 함수 실행이 완료되면 스택에서 가져옵니다.

잘 작동하는 포인터 주소를 전달해보십시오.

create_grid(&curr_grid);

편집 : 다음 링크를 확인이

Pointer tutorial

+0

포인터에 대한 내 이해가 잘못되었다는 것을 설명 할 때 메모리에서 무슨 일이 일어나고 있는지 그래픽으로 설명하고 싶습니다. 고마워, 지금은 내 두꺼운 두개골에 닿을 때까지 그 말을해야한다 :-) – mydoghasworms

+0

나는 대답이나 마이클을 받아 들일지 잘 모르겠다. 그는 함수에서 ***을 사용하여 코드를 더 잘 보여 주었지만 더 나은 설명을 제공했습니다. – mydoghasworms

0

방법은 규칙을 어떤 종류의 변수 (포인터를 전달 여부하는 방법을 알고 그래픽 표현에 당신을 도울 수있는 희망 동일하게 유지됨)은 다음과 같습니다.

여기에이라는 변수가 전달됩니다.값을 변경하고 값을 grid = malloc(...);으로 변경하고 싶다면 아무 것도 사용하지 않고 grid 만 사용하면 그리드 사본 만 있으며 grids 값을 변경하면 기능 외부에서 표시되지 않습니다. 이 경우 지금

: 이제

void create_grid(int ***grid) { 
    *grid = malloc(...); 
    ... 
} 

당신은 사용하여 그리드의 값에 액세스하는 등 '*', 당신이 알고, 그 그리드 정말 같은 함수가 반환 후 유지됩니다 이런 식으로 일을 변경 2 차원 배열에 대한 참조입니다.

이것은 간단합니다 (변수의 유형에 관계없이).

관련 문제