2017-11-17 7 views
0

이 코드는 일련의 함수 호출을 통해 행렬을 할당하지만 인쇄 할 때 세그먼트 오류 오류가 반환됩니다. 내가 함수 mat_fill()가 제대로 초기화되어 있다고 보여 제대로 작동에 사용하는 경우 내가 mat_print를 사용하여 매트릭스를 인쇄하면이에만 발생하는 것이동적으로 할당 된 행렬은 인쇄시 seg 오류를 발생합니다.

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

void mat_init(int** matx); 
void pp_init(int** matx); 
void p_init(int** matx); 
void mat_fill(int** matx); 
void mat_print(int** matx); 

int main(void) 
{ 
    srand((unsigned)time(NULL)); 
    int** matrix; 
    mat_init(matrix); 
    mat_print(matrix); 
    return 0; 
} 

void mat_init(int** matx) 
{ 
    pp_init(matx); 
} 

void pp_init(int** matx) 
{ 

    matx=malloc(4*sizeof(int*)); 
    p_init(matx); 
} 

void p_init(int** matx) 
{ 
    for(int i=0;i<4;i++) 
    { 
     *(matx+i)=malloc(4*sizeof(int)); 
    } 
    mat_fill(matx); 
} 

void mat_fill(int** matx) 
{ 
    for(int i=0;i<4;i++) 
    { 
     for(int j=0;j<4;j++) 
     { 
      *(*(matx+i)+j)=rand()%5; 
     } 
    } 
    //mat_print(matx); 
} 

void mat_print(int** matx) 
{ 
    printf("The matrix is:\n"); 
    for(int i=0;i<4;i++) 
    { 
     for(int j=0;j<4;j++) 
     { 
      printf("%1i|",*(*(matx+i)+j)); 
     } 
     puts(""); 
    } 
    puts(""); 
} 

주(), 주를 int로. 무엇이 문제입니까?

+0

왜? 매트릭스의 주소가 아닙니다. 이미 함수에 전달하고 있습니까? 왜 포인터를 첫 번째 함수 포인터에 전달해야합니까? – Adonai

+1

c의 모든 값이 전달됩니다. 'matx'를 함수에 넘겨 주면 마치'int'를 전달한 것처럼 로컬 복사본이 만들어집니다. 해당 로컬 복사본에서 수행하는 모든 조작은 해당 로컬 범위로 제한됩니다. 로컬 범위 외부에서 로컬 조작을 보길 원하면 값을 반환해야합니다 (또는 여기에서와 같이 포인터의 참조를 취소하고 포인터의 의미를 수정할 수 있습니다). 그러나'matx'는 당신이 그것을 여기에 전달할 때 아무 것도 가리 키지 않습니다. '& matx'를 넘겨 주면 뭔가를 가리키고 있지만 3 점 포인터를 다루는 것은 내 경험에 흔한 일이 아닙니다. – yano

+0

포인터에 대한 행렬 포인터가 함수에 전달 될 때 초기화되지 않기 때문에 작동하지 않습니다 ... if matrix = malloc (4 * sizeof (int *)); 주에서, pp_init를 없애 버렸습니다. 아마도 – Adonai

답변

1

는이 작업을 수행해야합니다

int** mat_init(int** matx); 
int** pp_init(int** matx); 

int main(void) 
{ 
    matrix=mat_init(matrix); 
} 

int** mat_init(int** matx) 
{ 
    return pp_init(matx); 
} 

int** pp_init(int** matx) 
{ 
    matx=malloc(4*sizeof(int*)); 
    p_init(matx); 
    return matx; 
} 

은 내가 변경하지 않은 일부 라인을 생략. 또 다른 옵션은 다음과 같습니다.

void mat_init(int*** matx); 
void pp_init(int*** matx); 

int main(void) 
{ 
    mat_init(&matrix); 
} 

void mat_init(int*** matx) 
{ 
    pp_init(matx); 
} 

void pp_init(int*** matx) 
{ 
    *matx=malloc(4*sizeof(int*)); 
    p_init(*matx); 
} 

다른 점 : 많은 장소에서 4 값을 사용하고 있습니다. 위험 해요. 대신 상수를 사용하십시오.

void foo(int a); 
{ 
    a = 6; 
} 

int main() 
{ 
    int a = 3; 
    foo(a); 
    printf("a = %d\n", a); // expecting this to print 6 

    return 0; 
} 

그 매개 변수가 함수에 전달 언제를 의미하므로 C의 모든 값에 의해 패스는, 그것의 로컬 복사본을 만들어 :

#define MAT_SIZE 4 

void mat_fill(int** matx) { 
    for(int i=0;i<MAT_SIZE;i++) { 
     for(int j=0;j<MAT_SIZE;j++) 
1

은 기본적으로 당신이하는 일은 이것이다 그 함수 내에서 그 범위는 그 함수 내에 만 존재한다; 포인터에 대한 예외는 없습니다. 내가 대신이 코드가있는 경우 :

void foo (int* ap2) 
{ 
    // there are now 2 pointers in memory that point to the same thing (main's a), namely 
    // ap2 on this stack frame and ap1 in the previous stack frame. 
    *ap2 = 6; 
    // ap2 is local to this function, but it _points_ to the same thing as 
    // ap1, so when we dereference it, changes to _what it points to_ are seen 
    // outside of this function. But once we return from this function, ap2 
    // ceases to exist 
} 

int main() 
{ 
    int a = 3; 
    int* ap1 = &a; 
    foo(ap1); 
    printf("a = %d\n", a); // now this prints 6 

    return 0; 
} 

당신이 함수에 mainmatx을 조작하려는 경우를, 당신은 그것을 가리키는 것을 을 수정하기 위해 그 기능에 그것과 역 참조 포인터를 전달해야 ~.

void foo (int*** matxp) 
{ 
    // matxp now points to matx in main 
    // dereference it here 
    *matxp = malloc(4 * sizeof(int*)); 
} 
int main() 
{ 
    int** matx; 
    foo(&matx); // pass the address of matx here, which is an int*** type 

    .... 

    // don't forget to clean up everything 
    return 0; 
} 

하지만 코멘트에 말했듯이, 나는 거의도 없어 3 성급 포인터를 본 적이 없다 /. 대신 값을 반환 할 수 있습니다.

int** foo() 
{ 
    matxp = malloc(4 * sizeof(int*)); 
    return matxp; // this will return NULL if malloc failed 
} 

int main() 
{ 
    int** matx = foo(); 

    .... 
    // do work, cleanup 
    return 0; 
}