C 프로그래밍 중에 계속 오류가 나는데 조언을 구하고 싶습니다.

xkzkwid의 이미지

코드 내용은, 동전던지기를 100,000번 해서
1. 앞면이 나온 전체 횟수
2. 앞면이 연속으로 나온 횟수
3. 2가 나온 횟수
3번의 보충설명을 하자면 예를 들어 한 번만 나온 게 3000번이고, 두 번 연속으로 나온 게 1000번일 때 출력화면에
1 \t 3000
2 \t 1000
이런 식으로 출력되는 겁니다.
프로그래밍 작성시 주어졌던 조건은
1. 꼭 배열을 사용하는 것
2. mollac 사용하지 말 것 이구요.
지금 아래의 프로그램을 실행하면 Segmentation fault (core dumped) 오류가 뜨네요.
포문을 남발한 탓인 것 같지만 이제 겨우 한 달 배운지라 딱히 다른 방법은 떠오르지 않아요..

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
 
int main(void){
        static int size = 1;
        int head = 0;
        int count = 0;
        int freq[100000];
        int combo[99999];
        int comboCount[99999];
        int i, j, temp;
 
        srand(time(NULL));
 
        for(i=0; i<100000; i++){
                freq[i] = rand()%2;
                if(freq[i] == 0)
                        head++; // 총 나온 횟수
                for(j=i+1; j<100000; j++){
                        if(freq[i]==0){
                                if(freq[i]==freq[j])
                                        count++; // 연속으로 몇 번 나왔는지 카운트
                                else
                                        count=0; // 1번만 나옴
                        }
                        else{ count = -1; } // 뒷면일 때
                        combo[j-1] = count;
                        count=0; // 카운트 초기화
                }
        }
 
        for(i=0; i<99999; i++){ // 섞여있는 연속 횟수를 정렬
                for(j=i+1; j<99999; j++){
                        if(combo[i]>combo[j]){
                                temp = combo[i];
                                combo[i] = combo[j];
                                combo[j] = temp;
                        }
                }
        }
        for(i=0; i<99999; i++){
                if(combo[i] != -1){
                        for(j=i+1; j<99999; j++){
                                if(combo[i]==combo[j])
                                        comboCount[size]++;
                                else {
                                        size++;
                                        while(combo[i]+1 != combo[j]){
                                                size++;
                                                comboCount[size] = 0;
                                        }
                                }
                        }
                }
        }
 
        printf("가장 긴 길이 : %d\n", comboCount[size]);
        printf("앞면이 나온 총 횟수 : %d\n", head);
        for(i=1; i<=size; i++)
                printf("%d\t%d\n", i, comboCount[i]);
 
        size = 0; // 사이즈 초기화
}

하여튼 도움을 주시면 감사하겠습니다. 어디서부터 손을 대야할 지 모르겠어요..
세벌의 이미지

동전던지기 하는데 2가 나오나요? 주사위도 아니고...

Segmentation fault (core dumped) 나올 때는

gcc -Wall

로 컴파일해서 나오는 메시지를 잘 읽어 보셔요.
shint의 이미지


1. 변수 초기화를 해줘야 합니다.
2. 변수 배열에 너무 큰 값을 넣지 않아야 합니다.
혹은 컴파일 옵션으로 변수의 스택 크기를 늘려줘야 합니다.

한줄씩 지우거나. 출력해서 확인해보세요.

http://codepad.org/iPqjvJYP

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
 
#define DF_FREQ 10
#define DF_COMBO 9
 
int main(void)
{
	static int size = 1;
	int head = 0;
	int count = 0;
	int freq[DF_FREQ];
	int combo[DF_COMBO];
	int comboCount[DF_COMBO];
	int i, j, temp;
 
	//변수값 초기화
	for (i = 0; i < DF_FREQ; i++)
	{
		freq[i] = 0;
	}
 
	for (i = 0; i < DF_COMBO; i++)
	{
		combo[i] = 0;
		comboCount[i] = 0;
	}
 
	srand(time(NULL));
 
	for (i = 0; i<DF_FREQ; i++)
	{
		freq[i] = rand() % 2;
 
		if (freq[i] == 0)
			head++; // 총 나온 횟수
 
		for (j = i + 1; j<DF_FREQ; j++)
		{
			if (freq[i] == 0)
			{
				if (freq[i] == freq[j])
					count++; // 연속으로 몇 번 나왔는지 카운트
				else
					count = 0; // 1번만 나옴
			}
			else
			{
				count = -1;
			} // 뒷면일 때
			combo[j - 1] = count;
			count = 0; // 카운트 초기화
 
		}
	}
 
	for (i = 0; i<DF_COMBO; i++)
	{ // 섞여있는 연속 횟수를 정렬
		for (j = i + 1; j<DF_COMBO; j++)
		{
			if (combo[i]>combo[j])
			{
				temp = combo[i];
				combo[i] = combo[j];
				combo[j] = temp;
			}
		}
	}
 
	for (i = 0; i<DF_COMBO; i++)
	{
		if (combo[i] != -1)
		{
			for (j = i + 1; j<DF_COMBO; j++)
			{
 
				if (combo[i] == combo[j])
				{
					comboCount[size]++;
				}
				else
				{
					size++;
					while (combo[i] + 1 != combo[j])
					{
						size++;
						comboCount[size] = 0;
					}
				}
			}
		}
	}
 
	printf("size %d\n", size);
 
	if (size == 0)
		return 0;
 
	printf("가장 긴 길이 : %d\n", comboCount[size]);
	printf("앞면이 나온 총 횟수 : %d\n", head);
 
 
 
	for (i = 1; i <= size; i++)
	{
		printf("%d\n", i);
		printf("%d\t%d\n", i, comboCount[i]);
	}
 
	size = 0; // 사이즈 초기화
	return 0;
 
}

----------------------------------------------------------------------------
젊음'은 모든것을 가능하게 만든다.

매일 1억명이 사용하는 프로그램을 함께 만들어보고 싶습니다.
정규 근로 시간을 지키는. 야근 없는 회사와 거래합니다.

각 분야별. 좋은 책'이나 사이트' 블로그' 링크 소개 받습니다. shintx@naver.com

ifree의 이미지

동전을 10만번 던진다고 10만 개 짜리 배열을 만들면 안됩니다.
100만번 던지면 100만 개 짜리 배열을 만들건가요?
저 정도의 배열은 스택을 넘어갈 가능성이 높습니다.
배열을 만드신다면, 다음과 같은 값을 저장하는 배열을 쓰세요.
앞면이 1회 연속으로 나오는 회수, 앞면이 2회 연속으로 나오는 회수...
앞면이 연속으로 나오는 회수를 예측할 수 없으므로, 크기가 고정된 배열보다는 벡터를 쓰는게 올바른 방법이겠죠.

또한 쓰신 랜덤 함수가 제대로 난수를 산출해 내는지 확인해 보시기 바랍니다.

이렇게 실제 수행을 통한 시뮬레이션의 샘플링 방법은 몬테카를로, 또는 라스베가스 기법이 대표적입니다. 이런 간단한 상황에는 어울리지 않지만 한 번 읽어 보시면 도움이 될 겁니다.

 의 이미지

for문 남발은 문제가 안 됩니다. for문을 의도에 맞게 제대로 사용했다면 말이지요.
아래는 질문자님 코드의 첫 for루프문입니다.

        for(i=0; i<100000; i++){
                freq[i] = rand()%2;
                if(freq[i] == 0)
                        head++; // 총 나온 횟수
                for(j=i+1; j<100000; j++){
                        if(freq[i]==0){
                                if(freq[i]==freq[j])
                                        count++; // 연속으로 몇 번 나왔는지 카운트
                                else
                                        count=0; // 1번만 나옴
                        }
                        else{ count = -1; } // 뒷면일 때
                        combo[j-1] = count;
                        count=0; // 카운트 초기화
                }
        }

두 가지 의문이 있는데 질문자님 스스로 답해 보시기 바랍니다.

1. 매 루프 반복 때마다 freq[i]에 난수를 대입합니다. 즉 freq 배열의 0~i까지만 난수가 들어가 있습니다.
그런데 내부 루프에서 j를 i+1부터 99999까지 돌리면서 freq[j]를 참조하고 있네요.
배열의 그 영역에는 난수가 들어 있을까요, 그렇지 않을까요?

2. 이 루프가 모두 실행되고 나면 combo 배열은 어떤 데이터를 담게 되나요?
우리말로 풀어 써보세요. 그리고 그걸 계산하기 위해 어떤 과정을 거치는지도 우리말로 설명해보세요.
이건 C언어 구사능력의 문제가 아니라 질문자님이 이 문제에 대해 어떤 풀이를 생각하셨는지를 여쭤보는 것입니다.

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.