C에서 함수의 반환값으로 동적으로 생성한 2차원 배열을 전달할 수 있을까요?

조회수 698회
#include <stdio.h>

int* array(){
    int a[3][3] = {{1,2,3}, {4,5,6}, {7,8,9}};
    return (int*) a;
}
int main() {
    int (*a)[3] = (void*)array();
    printf("%d ", a[0][0]);
    printf("%d ", a[2][2]);
}

실제로는 조금 더 복잡하게, 배열 크기는 함수의 인자로 전달받은 값으로 하고 배열의 원소도 하나씩 할당하도록 한 상태지만, 동일한 문제가 발생하는 좀 더 간단한 코드로 질문드립니다.

위 경우에 출력을 하게되면 동일한 인덱스의 값을 출력하는데도 불구하고 첫 번째 값은 정상적으로 나오는데 반해 두 번째 값은 가비지값이 나옵니다. 어떤 인덱스의 값을 출력하더라도 두 번째 이후에 출력했다면 가비지값이 출력되네요

해시코드의 코드 실행기로 실행해봤을때는 그런 문제가 없긴 한데, 대신 a[2][2]를 두 번째 이후에 출력하면 9 대신 0이 나옵니다.

함수 자체에서 반환 전에 출력을 하거나 해당 함수를 따로 정의하지 않고 main 함수에서 그대로 썼을 때에는 이러한 문제가 발생하지 않습니다.

array 함수에서 배열 선언할 때 int 앞에 static을 붙이면 에러가 안나는 것은 확인했지만, 실제 코드에서는(인자로 전달받은 값에 따라 배열을 동적으로 생성하므로) static을 쓸 수 없는 상황이라서 고민입니다.

제가 C에 대한 이해가 많이 부족해서 해결하지 못하는 문제인 것 같습니다.

어떤 식으로 해결할 수 있을까요?

1 답변

  • 좋아요

    0

    싫어요
    채택 취소하기

    array 함수 안에 선언된 a[3][3] 은 로컬변수로 스택영역에 잡힙니다. 함수를 종료하면, 해당 영역은 이후의 함수호출이나, 로컬변수 할당에 의해 다른 용도로 다시 사용되게 됩니다.

    로컬변수의 포인터를 리턴하는 것은, 방을 빼면서 쓰던 열쇠를 주는 거랑 같습니다.

    메모리를 할당하면, 힙에 생성이 되므로, 할당받은 포인터를 리턴하는 것이 옳겠습니다. 단 열쇠를 받은 사람은 열쇠를 다 쓰면, 방도 같이 없애줘야 하겠습니다.

    • malloc을 이용한 동적할당도 처음에 찾아보긴 했었는데 제가 제대로 찾지 못했나봅니다. 덕분에 해결했어요 감사합니다! HIAOAIH 2019.12.19 18:29

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)