【掲示板ご利用上の注意】

 ※題名は具体的に!
 ※学校の課題の丸投げ禁止!
 ※ソースの添付は「HTML変換ツール」で字下げ!
 ※返信の引用は最小限に!
 ※環境(OSとコンパイラ)や症状は具体的に詳しく!
 ※返信付き投稿の削除は禁止!
 ※マルチポスト(多重投稿)は慎んで!

 詳しくはこちら


本当はこんなに大きく書きたくはないのですが、なかなか守っていただけなくて…。
 守ってくださいね。お願いします。(by管理人)

C言語ソース⇒HTML形式ツール掲示板2こちら


管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧

No.22387

realloc関数
投稿者---643(2005/08/03 11:56:24)


realloc関数を使用してファイルから読み込んだ値を
構造体に格納しています。
ファイルの容量が一定でないため、reallocを使って
格納する構造体のサイズを変えているのですが、
reallocで、エラーが発生します。
たぶん、容量が確保できないためかと思うのですが
こうなった場合の対応はないのでしょうか。


この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:realloc関数 22388 まきじ 2005/08/03 12:01:13
<子記事> Re:realloc関数 22389 円零 2005/08/03 12:01:21
<子記事> Re:realloc関数 22391 RiSK 2005/08/03 12:37:43


No.22388

Re:realloc関数
投稿者---まきじ(2005/08/03 12:01:13)


>reallocで、エラーが発生します。

コンパイルエラーですか?
どういうエラーでしょうか?

>たぶん、容量が確保できないためかと思うのですが
>こうなった場合の対応はないのでしょうか。

realloc() は、確保に失敗した時は、NULL を返します。


この投稿にコメントする

削除パスワード

No.22389

Re:realloc関数
投稿者---円零(2005/08/03 12:01:21)


reallocで「構造体のサイズを変えている」っておかしくないですか?
構造体配列の要素数を変えていると言うのならわかりますが…


この投稿にコメントする

削除パスワード

No.22390

Re:realloc関数
投稿者---643(2005/08/03 12:37:11)


構造体配列の要素数を変えています。
戻りは、NULLです。
メモリ不足による確保のエラーになってます。
対応としてはないんでしょうか。


この投稿にコメントする

削除パスワード

No.22392

Re:realloc関数
投稿者---nop(2005/08/03 12:47:52)


>対応としてはないんでしょうか。

その対応を考えるのはあなたです。
要は仕様の問題です。


この投稿にコメントする

削除パスワード

No.22391

Re:realloc関数
投稿者---RiSK(2005/08/03 12:37:43)


まず,ソースとエラーをそのまま貼り付けましょう。


この投稿にコメントする

削除パスワード

No.22395

Re:realloc関数
投稿者---643(2005/08/03 14:07:03)


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

typedef struct {
    long  lineno ;
    char  *ymd ;
    char  *hms ;
    char  *read_data ;
} DATA ;


main()
{
    FILE *fp1,*fp2 ;
    DATA *data ;
    char buff[2048] ;
    char ymd[11] ;
    char hms[9] ;
    int  id01 ;
    int  id02 ;
    long lineno = 0 ;
    int n = 0 ;
    int size = 1024 ;
    int cnt = 0 ;
    int i ;
    int ret ;

    fp1=fopen("file.txt","r") ;
    if (fp1 == NULL) {
        printf("FilerOpen Error\n") ;
        return(1) ;
    }

    memset(buff, '\0', sizeof buff) ;
    data = NULL ;
    while (fgets(buff, sizeof buff, fp1)) {
        if (feof(fp1) != 0) {
            buff[strlen(buff)] = 0x0A ;
        }

        ++lineno ;
        memset(ymd, '\0', sizeof ymd) ;
        memset(ymd, '\0', sizeof hms) ;

        ret = sscanf(buff, "%s %s %*[^[][%d:%d" ,ymd,hms,&id01,&id02) ;
        if (ret != 4) {
            //WriteLogs(buff) ;
            continue ;
        }

        if (data == NULL || n >= size) {
             data = realloc(data, (size *= 2) * sizeof(DATA)) ;
             printf("New Address [%p]\n",data) ;
             if (data == NULL) {
                 printf("ProcessingError : memory Overflow") ;
                 return puts("out of memory"), 1 ;
             }
        }

        data[n].lineno = lineno ;
        data[n].ymd = strdup(ymd) ;
        data[n].hms = strdup(hms) ;
        data[n].read_data = strdup(buff) ;
        n++ ;

        memset(buff, '\0', sizeof buff) ;
    }

    free(data) ;

    fclose(fp1) ;

    return(0) ;
}




この投稿にコメントする

削除パスワード

No.22396

Re:realloc関数
投稿者---RiSK(2005/08/03 16:04:08)


全然本題とは関係ありませんが,
勝手に妖しいリファクタリングもどきをしました。
・不要な宣言削除。
・不要な include 削除。
・未定義動作になるコードの削除
 # printf("New Address [%p]\n",data) ; は
 # printf("New Address [%p]\n",(void*)data) ; とする必要があります。
・その他
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

typedef struct DATA{
    long  lineno;
    char  *ymd;
    char  *hms;
    char  *read_data;
} DATA;

int main(void)
{
    FILE * fp1;
    char buff[2048] = {0};
    long lineno = 0;
    DATA * data = NULL;
    int n = 0;
    int size = 1024;
    if ((fp1=fopen("file.txt", "r")) == NULL) {
        fprintf(stderr, "FilerOpen Error\n");
        return 1;
    }
    while (fgets(buff, sizeof buff, fp1)) {
        char ymd[11] = {0};
        char hms[9] = {0};
        int id01;
        int id02;
        if (feof(fp1) != 0) {
            buff[strlen(buff)] = 0x0A;
        }
        ++lineno;
        if (sscanf(buff, "%s%s %*[^[][%d:%d", ymd, hms, &id01, &id02) != 4) {
            continue;
        }
        if (data == NULL || n >= size) {
            DATA * tmp;
            tmp = realloc(data, (size *= 2) * sizeof(DATA));
            if (tmp) {
                data = tmp;
            } else {
                // ※dataの指すオブジェクトは生きているので,何か処理
                printf("ProcessingError : memory Overflow");
                return puts("out of memory"), 1;
            }
        }
        data[n].lineno = lineno;
        data[n].ymd = strdup(ymd);
        data[n].hms = strdup(hms);
        data[n].read_data = strdup(buff);
        ++n;
        memset(buff, '\0', sizeof buff);
    }
    free(data);
    fclose(fp1);
    return 0;
}

※tmpを使うことによってdataの指すオブジェクトを利用できます。
 reallocをdataで受けるとオブジェクトへアクセスできなくなります。

さて本題。

・メモリ確保失敗→即exit
・メモリ確保失敗→確保できていた範囲で処理→exit
・メモリ確保失敗→確保できていた範囲で処理
 →どっかのファイルに書いておく→続きを読む
 →どっかのファイルに追記

などでしょうか。
No.22392のとおりですね。


この投稿にコメントする

削除パスワード

No.22397

Re:realloc関数
投稿者---まきじ(2005/08/03 18:27:26)


>if (feof(fp1) != 0) buff[strlen(buff)] = 0x0A ;

この部分はこれで良いのですか?
これだと、\0 に上書きされてしまいますよ。

No 22237の問題は解決したのでしょか?

# 間違っていたらすいません。
# リモートホストが同じだったので、同一人物かと。


この投稿にコメントする

削除パスワード

No.22406

Re:realloc関数
投稿者---643(2005/08/03 23:45:32)


># 間違っていたらすいません。
># リモートホストが同じだったので、同一人物かと。
リモートホスト?
ホストがわかるのですか。同じなのを使っている人がいるのですね。

最終的には、仕様に行き着くのですね。
ありがとうございます。


この投稿にコメントする

削除パスワード

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧