C言語関係掲示板

過去ログ

No711 領域確保した構造体に値を設定したい

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

領域確保した構造体に値を設定したいのですが
投稿者---九十九(2003/07/21 22:30:34)


ファイルから読み込んだレコードを構造体に入れてqsotでソート
しています。
読み込むレコードの量は、決まっておらず、読み込んだ量に応じて
格納する構造体の領域を大きくしていこうとしているのですが、
読み込んだ値を構造体に設定するところで落ちてしまいます。

どこがわるいのでしょうか。
また、構造体に対しても領域確保できるのでしょうか。



#include <stdio.h>
#include <stdlib.h>
#include <string.h>


int comp(const void *p1, const void *p2)
{
    struct { char *code ; int count ; } *a = p1 ;
    struct { char *code ; int count ; } *b = p2 ;
    int diff ;

    diff = strcmp(a->code, b->code) ;

    return diff ? diff : a->count - b->count ;
}

main(argc,argv)
    int argc ;
    char *argv[] ;
{
    struct { char *code ; int count ; } **table ;
    char buf[1024] ;
    char code[1024] ;
    char num[4] ;
    int i = 0 ;
    int n = 0 ;
    int size = 1024 ;

   table = NULL ;
    while (fgets(buf, sizeof buf, stdin)) {
       buf[strlen[buf]) = '\0' ;
        pr = strtok(buff, ",") ;
        if(pr) strcpy(code, pr) ;
        pr = strtok(NULL, ",") ;
        if(pr) strcpy(num, pr) ;

        if (table == NULL || n >= size) {
            line = realloc(table, (size *= 2) * sizeof(sizeof(struct { char *code ; int count ; }))) ;
            if (line == NULL) {
                return puts("out of memory"), 1 ;
            }
        }

        i=n;
        table[i]->code = strdup(code) ;
        table[i]->count = atoi(count) ;
        n++ ;
    }

    qsort(table, n, sizeof(struct { char *code ; int count ; }), comp) ;

    for (i = 0 ; i < n ; i++) {
        printf("%s,%d\n",table[i].code,table[i].count) ;
    }

    return 0 ;
}


No.8546

Re:領域確保した構造体に値を設定したいのですが
投稿者---はろはろ(2003/07/21 22:47:44)


ぱぱっと見たところ

if (table == NULL || n >= size) {
で、真にならず
ループを抜けたところで

table[i]->code = strdup(code) ;
table[i]->count = atoi(count) ;

の部分で、落ちているのでは無いでしょうか。


それよりもこのソースコードはどこから持ってきたのですか?
ずいぶんと古い物のようですが……・・・

今風に書き直すと、すっきりして問題点もはっきりすると思います

No.8558

ふるいですか。
投稿者---九十九(2003/07/22 09:53:44)


古いですか。?
昔、習ったことと、サンプルなどを参考にしたのですが。
今風とは、どのようなものなのですいか。

確かに、構造体に値を設定するとことで、落ちています。
「Bus error(coredump)」しています。
領域の確保では、エラーにはなっていなないみたいですが。




#include <stdio.h>
#include <stdlib.h>
#include <string.h>


int comp(const void *p1, const void *p2)
{
    struct { char *code ; int count ; } *a = p1 ;
    struct { char *code ; int count ; } *b = p2 ;
    int diff ;

    diff = strcmp(a->code, b->code) ;

    return diff ? diff : a->count - b->count ;
}

main(argc,argv)
    int argc ;
    char *argv[] ;
{
    struct { char *code ; int count ; } **table ;
    char buf[1024] ;
    char code[1024] ;
    char num[4] ;
    char *pr ;
    int i = 0 ;
    int n = 0 ;
    int size = 1024 ;

    table = NULL ;
    while (fgets(buf, sizeof buf, stdin)) {
       buf[strlen(buf)] = '\0' ;
        pr = strtok(buf, ",") ;
        if(pr) strcpy(code, pr) ;
        pr = strtok(NULL, ",") ;
        if(pr) strcpy(num, pr) ;

        if (table == NULL || n >= size) {
            table = realloc(table, (size *= 2) * sizeof(struct { char *code ; int count ; })) ;
            if (table == NULL) {
                return puts("out of memory"), 1 ;
            }
        }

        i=n;
        table[i]->code = strdup(code) ;
        table[i]->count = atoi(num) ;
        n++ ;
    }

    qsort(table, n, sizeof(struct { char *code ; int count ; }), comp) ;

    for (i = 0 ; i < n ; i++) {
        printf("%s,%d\n",table[i]->code,table[i]->count) ;
    }

    return 0 ;
}


No.8559

Re:領域確保した構造体に値を設定したいのですが
投稿者---nop(2003/07/22 10:12:14)


>ファイルから読み込んだレコードを構造体に入れてqsotでソート
>しています。
>読み込むレコードの量は、決まっておらず、読み込んだ量に応じて
>格納する構造体の領域を大きくしていこうとしているのですが、
>読み込んだ値を構造体に設定するところで落ちてしまいます。
>struct { char *code ; int count ; } **table ;
>line = realloc(table, (size *= 2) * sizeof(sizeof(struct { char *code ; int count ; }))) ;
>table[i]->code = strdup(code) ;
>table[i]->count = atoi(count) ;

1.構造体へのポインタを格納するポインタ変数「table」への格納はいつするか?
2.何故に変数「table」はダブルポインタなのか?

この点に注意してもう一度ソースを追ってみて下さい。
間違いに気が付くでしょう。
あと、構造体はタグ名を定義するか、typedef 宣言しておいて、
「struct { char *code ; int count ; }」なんてまどろっこしい書き方はやめた方がよろしかと。

あと「sizeof(sizeof(struct { char *code ; int count ; }))」が、
どんな値を返すか確認するべきでは?

# sizeof 演算子で得られた値のサイズを求めるなんて、
# 「何をしたいの?」としか言いようがないですよ?

No.8561

Re:領域確保した構造体に値を設定したいのですが
投稿者---nop(2003/07/22 10:48:06)


とりあえず、こんな感じでどう?

/* ---------- Standard Header Include ---------- */
#include    <stdio.h>
#include    <stdlib.h>
#include    <string.h>
/* ---------- Structure Definition ---------- */
typedef struct
{
    char    *code;
    int     count;
} strTable;


int comp(const void *p1, const void *p2)
{
    /* ***** 内部変数定義 ***** */
    strTable    *a = (strTable *)p1;
    strTable    *b = (strTable *)p2;
    int         diff;

    /* ***** 比較 ***** */
    diff = strcmp( a->code, b->code );

    return diff ? diff : a->count - b->count ;
}

int main( void )
{
    /* ***** 内部変数定義 ***** */
    strTable    *table = NULL;
    char        buf[1024] = { '\0' };
    char        *code;
    char        *num;
    char        *p;
    int         size = 0;
    int         i;

    while( !feof(stdin) )    /* EOF までループ */
    {
        /* ***** プロンプト表示 ***** */
        fprintf( stderr, ">" );
        buf[0] = '\0';

        /* ***** 一行入力 ***** */
        fgets( buf, sizeof(buf), stdin );
        ( p=strrchr(buf,'\n') ) ? *p='\0' : 0;

        if( buf[0] )    /* 入力ありか? */
        {
            /* ***** 領域確保 ***** */
            size++;
            table = (strTable *)realloc( table, size*sizeof(strTable) );

            if( !table )    /* 確保エラーか? */
            {
                /* ***** エラー終了 ***** */
                puts( "out of memory!" );
                exit( EXIT_FAILURE );
            }
            /* ***** トークン分割 ***** */
            code = strtok( buf, "," );
            num  = strtok( NULL, "," );

            /* ***** テーブルに入力データを設定 ***** */
            table[size-1].code  = strdup( code );
            table[size-1].count = atoi( num );
        }
    }
    /* ***** 改行表示 ***** */
    puts( "\n" );

    /* ***** ソート ***** */
    qsort( table, size, sizeof(strTable), comp );

    for( i=0; i<size; i++ )
    {
        /* ***** データ表示 ***** */
        printf( "%s,%d\n", table[i].code, table[i].count );
    }

    /* ***** 領域解放 ***** */
    for( i=0; i<size; i++ )
    {
        /* ***** 文字領域解放 ***** */
        free( table[i].code );
    }
    free( table );

    return 0;
}


No.8563

ありがとうございます。
投稿者---九十九(2003/07/22 12:47:18)


ありがとうございます。

参考にさせていただきます。