C언어 Blocks[7][2]={0,}; 초기화 과정에서 스택 버퍼 오류가 발생

조회수 470회
static int m_Glass[7][2] = { {1,1},{1,1},{1,1},{1,1},{1,1},{1,1},{1,1} };


void InitBlocks(RECT blocks[][2], RECT& bound);
void DrawBlocks(HDC hdc, RECT blocks[][2]);

static RECT Blocks[7][2];

int randomnumber;
int rand_array[7];

InitBlocks(Blocks, clientR);

DrawBlocks(hdc, Blocks);

        for (int k = 0; k < 7; k++) {
            randomnumber = rand() % 2;
            rand_array[k] = randomnumber;
        }

        Blocks[7][2] = { 0, };//0이면 깨지는 유리, 1이면 강화 유리


        for (int row = 0; row < 7; row++) {
            Blocks[row][rand_array[row]] = { 1, };
        }

void InitBlocks(RECT blocks[][2], RECT& bound) {

    RECT r, t;
    int w, h;

    r = bound;
    r.right /= 2;

    r.top = 50;
    r.bottom = r.top + 40;

    w = r.right - r.left;
    h = r.bottom - r.top;

    for (int i = 0; i < 7; i++) {
        t = r;
        OffsetRect(&r, 0, h);

        for (int j = 0; j < 2; j++) {
            blocks[i][j] = t;
            OffsetRect(&t, w, 0);
        }
    }
}


void DrawBlocks(HDC hdc, RECT blocks[][2]) {
    COLORREF color = 255;

    for (int i = 0; i < 7; i++) {
        for (int j = 0; j < 2; j++) {
            if (m_Glass[i][j])
                DrawObject(hdc, blocks[i][j], RGB(0, 0, 0), RGB(0, color, color), 0);
        }
    }
}

전체 코드가 아니고 일부만 가져왓는데, Blocks[7][2]={0,}; 초기화 과정에서 스택 버퍼 오류가 발생한다고 합니다.. 구글링을 찾아봤지만, 스택 버퍼에 관한 오류는 대부분 for구문 설정을 잘못해서 그런데, 저는 for구문 설정은 제대로 한 것 같습니다.

제가 원하는 코드는 RECT라는 구조체에 0과 1을 초기화해서(일정 조건하에) 0또는 1의 값을 리턴받고 싶은데, 이걸 어떻게 해야할지 모르겠습니다.

말이 중구난방한거 같은데 도와주시면 정말 감사하겠습니다.

1 답변

  • 좋아요

    0

    싫어요
    채택 취소하기

    일단 올려주신 코드는 C언어 문법에 맞지 않습니다.

    Blocks[7][2] = { 0, };//0이면 깨지는 유리, 1이면 강화 유리Blocks[row][rand_array[row]] = { 1, }; 이런 코드는 허용되지 않는 문법입니다.

    스택 버퍼 오류가 발생한다고 하셨는데, Blocks는 전역 공간에 존재하기에 잘못된 메모리 접근에도 스택 오버플로우가 발생할 가능성은 낮습니다.

    스택 버퍼 오류란게 정확히 어떤 오류를 말하는지 파악하기 위해서 좀더 자세한 오류 메시지가 필요합니다.

    런타임에서 발생한건가요? 컴파일 타임에서 발생한건가요? 정말로 저 코드가 컴파일이 되서 실행이 가능했었나요?


    시작하기에 앞서 코드를 다시 보니 C++네요. 작성하신 코드는 C언어가 아닙니다.

    코드 에러 넘버는 C6200, C6386입니다. C6200의 경우에는 7이 다음 비스텍 버퍼에 대한 유효한 범위 0~6범위를 넘어간다고 나와 있고, C6386의 경우에는 버퍼 오버런이 발생했다며, 실제 쓰기 가능한 크기는 224바이트이지만 실제론느 256 바이트만 쓸 수 있습니다라고 나와있습니다.

    말그대로 잘못된 인덱스에 접근한다는 이야기입니다.

    static RECT Blocks[7][2];를 보면 Blocks는 크기가 7, 2이기에 접근 가능한 인덱스는 0~7과 0~1 입니다.

    그런데 Blocks[7][2] = { 0, };//0이면 깨지는 유리, 1이면 강화 유리에서는 72인덱스에 접근하기 때문에 해당 경고가 발생하고 있습니다.

    이차원 배열 구조체를 사용하여 각 구조체 안에 숫자(0또는 1)를 초기화하여 그 초기화 된 값을 리턴 받도록 코드를 짜고 싶은데

    코드를 보니 원하시는 동작은 Blocks의 값을 보고 조건에 따라 m_Glass0 또는 1을 대입하려는 것 같습니다. 그 조건은 난수에 기반하는 것 같구요.

    Blocks[7][2] = { 0, };//0이면 깨지는 유리, 1이면 강화 유리는 초기화하려는 역활을 갖지만 대상이 잘못되었습니다. 따라서 다음과 같이 m_Glass를 0으로 초기화 합니다.

    for (int i = 0; i < 7; ++i) {
        for (int j = 0; j < 2; ++j)
            m_Glass[i][j] = 0;
    }
    

    이 후 rand_array의 내용에 따라 m_Glass에 0 또는 1을 대입합니다.

    for (int i = 0; i < 7; ++i) {
        m_Glass[i][rand_array[i]] = 1;
    }
    

    이 후 DrawBlocks(hdc, Blocks);를 호출하면 m_Glass에 입력된 0 또는 1에 따라 해당하는 블록의 그림이 유리로될지 강화 유리로 될지 가 결정되겠네요.

    그럴려면 DrawBlocks()의 코드가 다음과 같아야겠죠.

    void DrawBlocks(HDC hdc, RECT blocks[][2]) {
        COLORREF color = 255;
    
        for (int i = 0; i < 7; i++) {
            for (int j = 0; j < 2; j++) {
                if (m_Glass[i][j])
                    DrawObject(hdc, blocks[i][j], RGB(0, 0, 0), RGB(0, color, color), 0);
                else
                    ; // 강화 유리에 대한 그리기
            }
        }
    }
    
    • 답변 감사드립니다! 일단 저 코드는 일부만 가져왔습니다!(일부만 가져왔어도 맞는지는 잘 모르겠습니다만..) 코드 에러 넘버는 C6200, C6386입니다. C6200의 경우에는 7이 다음 비스텍 버퍼에 대한 유효한 범위 0~6범위를 넘어간다고 나와 있고, C6386의 경우에는 버퍼 오버런이 발생했다며, 실제 쓰기 가능한 크기는 224바이트이지만 실제론느 256 바이트만 쓸 수 있습니다라고 나와있습니다. 컴파일 에러는 안나고 경고문만 뜹니다. 꼭 제가 한 방법 아니여도, 이차원 배열 구조체를 사용하여 각 구조체 안에 숫자(0또는 1)를 초기화하여 그 초기화 된 값을 리턴 받도록 코드를 짜고 싶은데, 다른 방안이 있으면 한번 부탁드리겠습니다. 감사합니다. 윤상혁 2021.12.8 15:37
    • 본문에 내용 추가하였습니다. 유동욱 2021.12.8 16:32
    • 정말 감사드립니다! 윤상혁 2021.12.8 16:48

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

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

(ಠ_ಠ)
(ಠ‿ಠ)