아하
검색 이미지
생활꿀팁 이미지
생활꿀팁생활
생활꿀팁 이미지
생활꿀팁생활
파란비둘기109
파란비둘기10920.06.27

c 프로그래밍 세그멘테이션 오류

계속 세그멘테이션 오류가 뜨는데 어디서 잘못된건지 모르겠습니다ㅜㅜㅜㅜㅜ

조언이나 고칠 점 부탁드립니다 ㅜㅜㅜ

#include <stdio.h>

#include <stdlib.h>

void trianglePrint( int **arr, int i, int j)

{

printf("%d ", arr[i][j]);

}

void pascalTriangle (int **arr, int i, int j)

{

for (j = 1; j <= i; j++)

{

arr[i][j] = arr[i - 1][j - 1] + arr[i - 1][j];

trianglePrint(arr, i, j);

}

}

int main()

{

int a, i, k, j;

scanf("%d", &a);

int **arr = NULL;

arr = (int *) malloc ( sizeof(int ) * a);

arr[0] = (int ) malloc ( sizeof(int) a*a );

for( int k = 1; k < a; k++)

{

arr[k] = arr[ k-1 ] + a;

}

for (i = 1; i <= a; i++)

{

pascalTriangle(arr, i, j);

printf("\n");

}

return 0;

}

55글자 더 채워주세요.
답변의 개수
2개의 답변이 있어요!
  • 안녕하세요.

    먼저, 아래 부분은 "sizeof(int) a * a"라고 오타를 정정한 후,

    arr[0] = (int ) malloc ( sizeof(int) a*a );

    문의주신 "Segmentation fault"가 발생하는 이유를 먼저 설명드리면,

    2차원 배열(arr)에 동적 메모리를 할당하는 코드가 잘못되어,

    이후 pascalTriangle() 함수에서 "arr"의 잘못된 Index를 참조하여 문제가 발생했습니다.

    2차원 배열에 대해 메모리를 동적 할당하는 방법은 아래와 같습니다.

    int row = 0, col = 0; scanf("%d %d", &row, &col); int **d_arr = malloc(sizeof(int *) * row); // 배열의 세로에 대해 메모리 할당 for (int i = 0; i < row; i++) // 세로 크기 만큼 반복 { d_arr[i] = malloc(sizeof(int) * col); // 각 배열의 세로에 해당하는 "가로"에 대해 메모리 할당 }

    추가로 2차원 배열의 메모리 해제 방법은 메모리 할당 과정과 반대의 순서로 진행하면 되며, 아래와 같습니다.

    for (int i = 0; i < row; i ++) { free(d_arr[i]); } free(d_arr);

    마지막으로 구현하고 싶어하신걸로 보이는 "Pascal's triangle"에 대해서도 추가 문의해주시면, 답변드리도록 하겠습니다.

    좋은 하루 되세요 :)


  • #include <stdio.h> #include <stdlib.h> void trianglePrint(int **arr, int i, int j) { printf("%d ", arr[i][j]); } void pascalTriangle(int **arr, int i, int j) { for (j = 1; j <= i; j++) { arr[i][j] = arr[i - 1][j - 1] + arr[i - 1][j]; trianglePrint(arr, i, j); } } int main() { int a, i, k, j; scanf("%d", &a); int **arr = NULL; arr = (int **) malloc(sizeof(int *) * a); arr[0] = (int *) malloc(sizeof(int) * a * a); for(int k = 1; k < a; k++) { arr[k] = arr[k - 1] + a; } for (i = 1; i <= a; i++) { pascalTriangle(arr, i, j); printf("\n"); } return 0; }

    이 코드로 질문 주셨는데요, pascalTriangle과 trianglePrint를 별도의 함수로 빼지 않으면

    // 중략 int **arr = NULL; arr = (int **) malloc(sizeof(int *) * a); arr[0] = (int *) malloc(sizeof(int) * a * a); for(int k = 1; k < a; k++) { arr[k] = arr[k - 1] + a; } // -------------------------------------------- for (i = 1; i <= a; i++) { for (j = 1; j <= i; j++) { arr[i][j] = arr[i - 1][j - 1] + arr[i - 1][j]; printf("%d ", arr[i][j]); } printf("\n"); } // 후략

    이렇게 되겠네요.

    for(i = 1; i <= a; i++) { for(j = 1; j <= i; j++) { arr[i][j] = arr[i - 1][j - 1] + arr[i - 1][j];

    arr[i - 1][j]이나 arr[i]에서 arr이 할당받은 범위를 초과하게 됩니다.

    int **arr = (int **) malloc(sizeof(int *) * a); // int* × a개 for(i = 0; i < a; i++) { // a번에 나눠서 arr[i] = (int *) malloc(sizeof(int) * a); // int × a개 }

    할당을 이렇게 받으면 malloc을 a+1번 호출해야 합니다. 이걸 두번만의 호출로 할당받을 수 있도록 바꾼 것입니다.

    int **arr = (int **) malloc(sizeof(int *) * a); // 위와 같음 arr[0] = (int *) malloc(sizeof(int) * a * a); // int × a × a개 할당 // arr[0]은 위 줄에서 초기화했으므로, arr[1]부터 arr[a - 1]까지 초기화하면 됩니다. for(int k = 1; k < a; k++) // k를 1부터 a-1까지 { arr[k] = arr[k - 1] + a; // arr[k] = &arr[k - 1][a];와 같음 } // arr[k - 1]의 마지막 주소가 arr[k]의 시작 주소가 되도록

    이 부분이 메모리를 할당받는 부분인데요, 여기서는 arr[0]을 먼저 초기화했기 때문에 for를 1부터 시작한 것입니다.

    for(i = 1; i <= a; i++) { for(j = 1; j <= i; j++) { arr[i][j] = arr[i - 1][j - 1] + arr[i - 1][j];

    이 부분도 위와 마찬가지로 일부를 먼저 초기화하고, 그 일부를 기반으로 나머지를 초기화하려는 것 같은데요,
    arr[n][n+1]과 arr[n][0]은 먼저 초기화해야 하는데, 초기화를 안 했네요. 무슨 의도인지 모르겠어요...ㅠ

    그리고 배열은 0부터 길이까지가 아니라 0부터 길이-1까지이기 때문에 i <= a가 아니라 i < a로 해야 합니다.

    파스칼의 삼각형#include <stdio.h> #include <stdlib.h> int main() { int a, i, j; scanf("%d", &a); int **arr = NULL; arr = (int **) malloc(sizeof(int *) * a); arr[0] = (int *) malloc(sizeof(int) * a * a); for(i = 1; i < a; i++) { arr[i] = arr[i - 1] + a; arr[i - 1][i] = 1; // 미리 초기화할 값 } arr[0][0] = 1; // 미리 초기화할 값 for(i = 1; i < a; i++) // <=를 <로 고침 { arr[i][0] = 1; // 미리 초기화할 값 for(j = 1; j <= i; j++) { arr[i][j] = arr[i - 1][j - 1] + arr[i - 1][j]; printf("%d ", arr[i][j]); } printf("\n"); } return 0; }

    그 점을 모두 고치면 이렇게 되겠네요.

    그리고 조언도 구하셨는데,
    코드를 올리실 때는 뭐 하는 코드인지 의도를 설명해주세요.
    코드만 올리면, 심지어 그 코드가 제대로 돌아가지도 않으면 무슨 의도의 코드인지 알 수 없습니다.