buffer overflow detected 에러

rayman의 이미지

길이가 1,000,000 이하인 2진수를 8진수로 변환하는 문제를 해결하고 있는데요.

Visual C 에서는 에러가 발생하지 않는 코드가 online judge 시스템에서 실행하면 다음과 같은 에러가 발생합니다.

=> Runtime Error:[ERROR] A Not allowed system call: runid:175636 callid:146

*** buffer overflow detected ***: ./Main terminated

2진수를 3의 배수 개로 맞춘 후(2진수의 길이가 3의 배수가 아닐 때, 0 혹은 00을 2진수의 최상위 비트에 붙였어요)

3개씩 끊어서 10진수로 변환시키는 방식으로 문제를 해결했어요.

왜 위와 같은 오류가 발생하는지 알고 싶습니다. 어떻게 해결할 수 있을까요?

제가 작성한 코드입니다.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
 
int main()
{
	char bin[1000001];
	char tmp[10], convert[10];
	int i, j, num;
 
	gets(bin);
	if(strlen(bin) % 3 == 1) {
		strcpy(tmp, "00");
		strcat(tmp, bin);
		strcpy(bin, tmp);
	}
	else if(strlen(bin) % 3 == 2) {
		strcpy(tmp, "0");
		strcat(tmp, bin);
		strcpy(bin, tmp);
	}
 
	for(i = 0; i < strlen(bin); i += 3) {
		for(j = 0; j < 3; j++)
			convert[j] = bin[i + j];
		convert[3] = '\0';
 
		sscanf(convert, "%d", &num);		
		switch(num) {
		case 0 :	putchar('0');	break;
		case 1 :	putchar('1');	break;
		case 10 :	putchar('2');	break;
		case 11 :	putchar('3');	break;
		case 100 :	putchar('4');	break;
		case 101 :	putchar('5');	break;
		case 110 :	putchar('6');	break;
		case 111 :	putchar('7');	break;
		}
	}
	puts("");
	return 0;
}
klara의 이미지

rayman의 이미지

xylosper 님이 올려 주신 것을 보니 strcat을 잘못 사용했네요...

그래서 tmp 배열의 크기를 1,000,010로 하고 실행을 했는데, stack overflow 에러가 났어요.

그래서 strcat 함수를 사용하지 않는 방법으로 코드를 수정했고, bin 배열에 정상적으로 3의 배수 갯수 만큼의 숫자가 입력됨을 확인했어요.

수정한 코드가 숫자가 비교적 작은 테스트 케이스에 대해서는 정상적으로 작동하는데, 1,000,000 개로 이루어진 2진수 숫자를 입력하면 코드의 맨 마지막 for문이 무한루프가 되네요.

왜 이렇게 되는 거에요?

수정한 코드입니다.

#include <stdio.h>
#include <string.h>
 
int main()
{
	char bin[1000010];
	char convert[10];
	long long i, j, num, len;
 
	gets(bin);
	if(strlen(bin) % 3 == 1) {
		len = strlen(bin);
		for(i = len - 1; i >= 0; i--) {
			bin[i + 2] = bin[i];
		}
		bin[0] = bin[1] = '0';
		bin[len + 2] = '\0';
	}
	else if(strlen(bin) % 3 == 2) {
		len = strlen(bin);
		for(i = len - 1; i >= 0; i--) {
			bin[i + 1] = bin[i];
		}
		bin[0] = '0';
		bin[len + 1] = '\0';
	}
 
	len = strlen(bin);
	for(i = 0; i < len; i += 3) {
		strncpy(convert, bin + i, 3);
		convert[3] = '\0';
		sscanf(convert, "%lld", &num);
 
                switch(num) {
		case 0 :	putchar('0');	break;
		case 1 :	putchar('1');	break;
		case 10 :	putchar('2');	break;
		case 11 :	putchar('3');	break;
		case 100 :	putchar('4');	break;
		case 101 :	putchar('5');	break;
		case 110 :	putchar('6');	break;
		case 111 :	putchar('7');	break;
		}
	}
	puts("");
	return 0;
}
klara의 이미지

무한루프라는건 어떻게 확인하셨나요? 루프안에서 i가 len보다 커지는 걸 찍어보신건가요?

rayman의 이미지

무한루프 돌아가는 게 아니라 시간이 좀 오래 걸리는 문제였어요..

감사합니다. ^^

마잇의 이미지

저도 이런 적 있어요.

실행하고 곧바로 뭔가 뱉어 내겠지 했는데 멍하니 돌아갈 때 '무한 루프 도는 구나' 하고 컨트롤씨 누르려는 찰나,

'형님 끝났습니다'

하고 결과 뱉을 때.

좀 미안해요. 의심해서.


--
마잇

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.