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 답변
-
일단 올려주신 코드는 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이면 강화 유리
에서는 7과 2인덱스에 접근하기 때문에 해당 경고가 발생하고 있습니다.이차원 배열 구조체를 사용하여 각 구조체 안에 숫자(0또는 1)를 초기화하여 그 초기화 된 값을 리턴 받도록 코드를 짜고 싶은데
코드를 보니 원하시는 동작은
Blocks
의 값을 보고 조건에 따라m_Glass
에 0 또는 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
댓글 입력