역시 리눅스는 메모리 관리를 철저히 하는군요.

noblepylon의 이미지

오늘 저녁에 USACO Training 1번 문제를 풀었더랍니다. 그냥 문자열을 두개 입력받아서 숫자로 변환한뒤 47로 나눈 나머지가 같은가 판별하는 쉬운 문제였지요. 저는 다음과 같은 코드를 작성했습니다:

(선략)
int main()
{
	char CometName[6]; // CometName: the name of the comet approaching
	char GroupName[6]; // GroupName: the name of the group trying to ride on the UFO
 
	FILE* fin = fopen("ride.in", "r"); // Open ride.in for reading
	FILE* fout = fopen("ride.out", "w"); // Open ride.out for writing
 
	// Get CometName & GroupName
	fscanf(fin, "%s", CometName);
	fscanf(fin, "%s", GroupName);
(후략)

ride.in 파일:
COMETQ
HVNGAT

윈도우에서는 아무런 문제없이 실행이 되었습니다. 그런데 USACO채점시스템에게 보냈더니 0.1초도 안돼서 컴파일 에러를 멋지게 냈습니다.

  > Run 1: Execution error: Your program had this runtime error:
        Exceeded memory or invalid memory reference. The program ran for
        0.000 CPU seconds before the error. It used 2848 KB of memory.

몇시간동안 노가다로 디버깅을 시도했습니다. 그러나 아무 버그도 찾지 못했습니다. 채점시스템이 GCC를 사용한다는 것을 문득 깨닫고는 리눅스에 이클립스를 깔아서 다시 실행해봤습니다. 아, 이제야 런타임 에러가 하나 뜨네요.

런타임 에러를 없애려고 엄청 삽질하다가 그냥 아무생각없이 CometName과 GroupName의 크기를 10으로 늘렸습니다. 이제 되더군요.
그제야 저는 깨달았습니다.
실제로 위 프로그램은 파일 포인터가 파일 끝에 도달할 때 전송되는 EOF(파일 끝!)코드를 GroupName[7]에 넣으려고 시도하게 됩니다.
윈도는 이것을 눈감아준거고, 리눅스는 눈감아 주지않은 거죠. 뭐.

이제야 왜 리눅스가 안정성의 상징으로 추앙받는지 이해가 가는군요-_-;
메모리 한칸(4바이트)도 내주지 않으려는 이 꼼꼼함에 감탄할 뿐입니다.

eungkyu의 이미지

직접 실행해본 것은 아니지만

여섯자리 글자를 스트링으로 문자 배열에 넣을려면 널문자까지 해서 7자가 필요하기 때문 아닌가요?
EOF랑은 관계없는것 같습니다.

kslee80의 이미지

엄밀하게 이야기하자면 메모리 관리와는 관련이 없습니다.

위의 코드는 윈도우에서도 런타임 에러를 낼 수도 있고,
리눅스에서 아무런 문제 없이 동작할 수도 있는 코드입니다.

어쩌다보니 윈도우에서는 아무런 문제 없이 동작했고,
리눅스 및 USACO 채점시스템에서는 에러를 낸 것일 뿐입니다.

boy0의 이미지

[6] 말고 더 작은 숫자로 바꿔서 해보세요 ^^
더 재밌습니다.

JuEUS-U의 이미지

저기 USACO 채점서버에서는 _asm 같은거 안되려나요 :)

noblepylon의 이미지

_asm이 표준이 아니라면 gcc에서 지원할 리가 없는데...

ps. C를 사용하는데 굳이 어셈블리어를 쓸 필요가 있나 싶습니다.
---
"The truth will make you free."(John 8:32)
"I am the way, and the truth, and the life: no one comes to the Father but through Me."(John 14:6)

---
“내게 능력주시는 자 안에서 내가 모든 것을 할 수 있느니라.”(빌립보서 4:13)

정태영의 이미지

vc 에서처럼 asm block 은 지원하지 않지만 __asm__ 은 지원합니다.

--
오랫동안 꿈을 그리는 사람은 그 꿈을 닮아간다...

http://mytears.org ~(~_~)~
나 한줄기 바람처럼..

오랫동안 꿈을 그리는 사람은 그 꿈을 닮아간다...

http://mytears.org ~(~_~)~
나 한줄기 바람처럼..

cppig1995의 이미지

gcc가 C99 reference implementation도 아니고, 모든 표준만 구현할 이유가 없습니다.
(모든 ~만은 if and only if의 의미로 쓴 건데 조금 어색하지요?)
gcc에는 (아시겠지만) 비표준 기능이 넘치지 않나요.
--
임수 서룬뫼 윤 희수 {cppig1995}

Real programmers /* don't */ comment their code.
If it was hard to write, it should be /* hard to */ read.

bushi의 이미지

비표준이 넘친다라니.. 마치 "표준은 이렇지만 GCC는 전혀 엉뚱하게 구현한 것이 수두룩하다" 처럼 들립니다.

"이런 내용을 표준으로 정하지는 않겠다. 컴파일러 나름대로 하거라"
표준에 있는 내용이므로 비표준이라는 말은 적당치 않습니다.

OTL

dg의 이미지

gcc에도 비표준 있습니다. 물론 표준대로 짠 코드는 다 올바르게 컴파일 되는걸로 알고 있습니다만...

몇가지 살펴보면

#include <stdio.h>
 
int f()
{
        int g() // nested function
        {
                return 1;
        }
        return g();
}
 
int main(void)
{
        int a = ({int b = f(); ++b;}); // statement expression
        typeof(a) newvar = a; // typeof
        printf("%d\n", newvar);
        return 0;
}

gcc의 확장들에 대한 설명입니다.
http://gcc.gnu.org/onlinedocs/gcc-4.3.0/gcc/C-Extensions.html
이중에는 C99에서 표준으로 된 것도 있습니다.