C言語関係掲示板

過去ログ

No.610.配列が壊れる!?

[戻る] [ホームページ]
No.5884

配列が壊れる!?
投稿者---M(2003/04/21 16:28:53)


COBOLプログラムしか経験がなく、仕事の都合でC言語をはじめて約1週間になります。
色々なサイトを見ながら、何とか動くようになってきたのですが、
データ件数を増やしたとたん、不可思議な挙動をしてしまい、
解決できません。
お知恵を拝借させていただきたく、書き込みさせていただきます。

やりたいことは、テキストファイルの全件を読み込み、
全件配列に格納し、昇順に並び替えて、全件出力する、
という単純なものです。

問題となっているのは、422件目を読み込んだ後、
レコードを配列に入れる際に、データがNULLになってしまうというものです。
入力データは最大150バイト、最大500件を想定しています。

以下、ソースを載せます。

#include <stdio.h>    /* standard i/o */
#include <stdlib.h>
#include <string.h>

#define maxnum 500    /* 最大処理数 */

    int comp(const void *a, const void *b)
    {
        return strcmp(*(char **)a, *(char **)b);
    };


main(int argc, char *argv[])
{
    int count_max = 0;    /* job count */
    int i;

     char table[150], *index_table[maxnum]; 
    char buf[150];        /* Input file */
    FILE *fp1;            /* file pointer */

    /* ======================= */
    /* ファイルのオープン       */
    /* ======================= */
    fp1 = fopen(argv[1],"r");
    if (fp1 == NULL){
        printf("open file failed \n");
        exit(-1);
    }

    /* ======================= */
    /* ファイルの読み込み       */
    /* ======================= */
    while(fgets(buf,150,fp1)!=NULL) {
        printf ("%d%s",count_max, buf);
        /* 構造体配列に格納 */
          index_table[count_max] = strdup(buf);

        /* for debug */
        printf ("%d%s",count_max, index_table[count_max]);

          count_max = count_max + 1;    /* count_max up */
        if (count_max > maxnum){
            printf ("max over!");
            exit(-1);
        }
    }

    /* ======================= */
    /* ファイルのクローズ       */
    /* ======================= */
    fclose(fp1);

    /* ======================= */
    /* 配列をクイックソートする */
    /* ======================= */
    printf("ソートするよ!\n");
    qsort(index_table, count_max, sizeof(char *), comp);

    /* ======================= */
    /* レポートの書き出し       */
    /* ======================= */
    printf("書き出し開始\n");
    for (i=0; i <= count_max; i++) {
        /* ソートしたレコードを出力する */
        printf("%d :%s",i, index_table[i]);
    }
return 0;
}


デバッグ用にprintfでデータを表示しています。
35行目で読み込んだレコードを表示し、
40行目で配列の内容を表示しているのですが、
この2行は思惑通りに行けば同じ内容が出力されるはずなのに、
先述の422件目以降上手く行きません。
それに引っ張られて、後のqsortされたデータにもNULLが混ざります。

長文になってしまいましたが、よろしくご指導お願いします。

No.5886

Re:配列が壊れる!?
投稿者---TDa(2003/04/21 18:07:26)


実データを出すのは差し障りがあるのかもしれませんが

>問題となっているのは、422件目を読み込んだ後、
>レコードを配列に入れる際に、データがNULLになってしまうというものです。
>入力データは最大150バイト、最大500件を想定しています。

その問題の行前後に問題が有ると考えるのがふつうです。
実データを出すのは差し障りがあるのかもしれませんができる範囲でその前
後を見せてもらえればアドバイスがもらえるかもしれませんよ。


No.5888

Re:配列が壊れる!?
投稿者---かずま(2003/04/21 19:24:51)


> レコードを配列に入れる際に、データがNULLになってしまうというものです。
> 入力データは最大150バイト、最大500件を想定しています。

こういう質問をするときは、環境(コンパイラの名前)を書きましょう。

150バイトが 500件だと、75KB 必要ですね。LSI C-86 の試食版だと、small
model しかありませんから、64kB よりもずっと少ないデータしか扱えません。

index_table[count_max] = strdup(buf); のあとに、
if (index_table[count_max] == NULL) { puts("out of memory"); exit(1); }
を入れてみれば、そこでメモリが足りなくなったことが分かるでしょう。

No.5893

Re:配列が壊れる!?
投稿者---(2003/04/21 21:58:55)


>こういう質問をするときは、環境(コンパイラの名前)を書きましょう。

おっしゃる通りです。
初めての質問に舞い上がっておりました(汗)

Windows2000Pro、WindowsNT WKSt4.0、WindowsXP Proの3つで試し、
CコンパイラはLSI C-86試食版です。

>150バイトが 500件だと、75KB 必要ですね。LSI C-86 の試食版だと、small
>model しかありませんから、64kB よりもずっと少ないデータしか扱えません。

ああ〜。そういうことですか。
422件で63300バイト、リアルな数字です。
おそらくコレで間違いないでしょう。

ど素人の疑問を一発で解決していただきまして、
本当にありがとうございました。

No.5889

Re:配列が壊れる!?
投稿者---ぬるぽ(2003/04/21 19:35:32)


>問題となっているのは、422件目を読み込んだ後、
>レコードを配列に入れる際に、データがNULLになってしまうというものです。
>入力データは最大150バイト、最大500件を想定しています。

私もそんなに詳しくは無いのですが、fgets()は指定されたサイズよりも
一文字少なく読み込むようですが、指定サイズ=150で大丈夫ですか?

>以下、ソースを載せます。
>デバッグ用にprintfでデータを表示しています。
>35行目で読み込んだレコードを表示し、
>40行目で配列の内容を表示しているのですが、
>この2行は思惑通りに行けば同じ内容が出力されるはずなのに、
>先述の422件目以降上手く行きません。
>それに引っ張られて、後のqsortされたデータにもNULLが混ざります。

422件目の文字数が改行込みで150字だとそうなっちゃったり
しそうな気がしますが。

間違ってるかもしれません。私も勉強させてもらいます。

No.5901

<解決> Re:配列が壊れる!?
投稿者---M(2003/04/22 09:46:31)


皆さん、大変お世話になりました。
かずま様のご指摘のとおりでした。

検証のため、BC++コンパイラを導入して
テストしてみたところ、
全く問題なく稼動してくれました。

ご助言頂いた皆さん、誠にありがとうございました。