掲示板利用宣言

 次のフォームをすべてチェックしてからご利用ください。

 私は

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

掲示板2

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

No.29871

実行時エラー
投稿者---ゲータレイダー(2007/03/06 18:25:53)


何処が悪いのか解りません。どなたかご教授願います。
コンパイラ:Borland
OS:XP Home edition

/* ファイルから1行ずつ読み込み画面に表示させる。*/
/* 可変長で実装 */
/* グローバル変数は使用しないものとする。*/

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

#define ALLOC_SIZE 256

/*************************************** 
* reallocで確保した領域にchを追加する。
***************************************/
void add_character(char **line_buffer_p,  int ch,  
                        int *current_alloc_size_p,  int *current_used_size_p) {

    assert(*current_alloc_size_p >= *current_used_size_p);

    if (*current_alloc_size_p == *current_used_size_p) {

        *line_buffer_p = realloc(*line_buffer_p, (*current_alloc_size_p + ALLOC_SIZE) * sizeof(char*));
        *current_alloc_size_p += ALLOC_SIZE;
    }

    *line_buffer_p[*current_used_size_p] = ch;    
    (*current_used_size_p)++;
}

/*******************************************
*   ファイルから一行ずつ読み込む
*******************************************/
char *read_line(FILE *fp) {

    char    *ret;
    int ch;

    char    *line_buffer = NULL;
    int     current_alloc_size = 0;
    int     current_used_size = 0;

    while ((ch = getc(fp)) != EOF) {

        if (ch == '\n') {
            add_character(&line_buffer,  '\0',  &current_alloc_size,  &current_used_size);
            break;
        }

        add_character(&line_buffer,  ch,  &current_alloc_size,  &current_used_size);    
    }

    if (ch == EOF) {

        if (current_used_size > 0) {
            add_character(&line_buffer, '\0', &current_alloc_size, &current_used_size);
        } else {
            return NULL;
        }
    }

    ret = malloc(current_used_size * sizeof(char));
    strcpy(ret, line_buffer);

    return ret;
}

int main(void) {

    char    *hoge;

    while ((hoge = read_line(stdin)) != NULL) {
        printf("%s\n", hoge);
    }

    return 0;
}



この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:実行時エラー 29873 ぽへぇ 2007/03/06 19:23:57


No.29873

Re:実行時エラー
投稿者---ぽへぇ(2007/03/06 19:23:57)


> *line_buffer_p[*current_used_size_p] = ch;
(*line_buffer_p)[*current_used_size_p] = ch;

アドバイス:
原因を追い込めるようになると自分自身で修正できるようになります。
「2文字目(以降)の追加時に add_character() 内で」くらいは
書けるようになりましょう。



この投稿にコメントする

削除パスワード

No.29875

Re:実行時エラー
投稿者---ゲータレイダー(2007/03/06 21:51:28)


ぽへぇ様、返信ありがとうございます。

>「2文字目(以降)の追加時に add_character() 内で」くらいは
>書けるようになりましょう。

printf()デバック(?)で一応見当は付いたのですが・・・
言葉が足りませんでした。すみません。

優先順位の問題ということでよろしいでしょうか。指摘されるまで
検討も付きませんでした。これで解決しました。ありがとうございます。


この投稿にコメントする

削除パスワード

No.29879

Re:実行時エラー
投稿者---かずま(2007/03/07 01:01:08)


> 優先順位の問題ということでよろしいでしょうか。指摘されるまで
> 検討も付きませんでした。これで解決しました。ありがとうございます。

本当に解決したと言えるのでしょうか?
realloc や malloc した領域を free していないので、読み込入力の
2倍以上のメモリーが必要です。


この投稿にコメントする

削除パスワード

No.29880

Re:実行時エラー
投稿者---ぽへぇ(2007/03/07 07:53:35)


No.29879 かずま さん
>realloc や malloc した領域を free していないので、読み込入力の
>2倍以上のメモリーが必要です。

あー。素で見落としてた。orz

No.29875 ゲータレイダー さん
>優先順位の問題ということでよろしいでしょうか。

私自身はこの手(優先度)のことを考えるのが面倒だし、
その場で何とかなっても、自分で書いたコードにもかかわらず
後で見返して意味不明な状態になることが経験上わかっている ^^; ので、
極力手間がかからない方法を考えます。

typedef struct  tag_StrInfo {
  char* m_pStr;
  int  m_AllocSize;
  int  m_UsedSize;
} StrInfo;


void add_character(StrInfo* pInfo, int ch)
{
  assert(pInfo->m_AllocSize >= pInfo->m_UsedSize);

    if (pInfo->m_AllocSize == pInfo->m_UsedSize) {
      pInfo->m_pStr = (char*)realloc(pInfo->m_pStr,
          (pInfo->m_AllocSize + ALLOC_SIZE));
      pInfo->m_AllocSize += ALLOC_SIZE;
    }

    pInfo->m_pStr[pInfo->m_UsedSize] = ch;
    pInfo->m_UsedSize++;
}



この投稿にコメントする

削除パスワード

No.29904

Re:実行時エラー
投稿者---かずま(2007/03/10 09:27:48)


>> realloc や malloc した領域を free していないので、読み込入力の
>> 2倍以上のメモリーが必要です。
>
> あー。素で見落としてた。orz

実は、他にも見落としていたところがあります。
元のプログラムでは realloc のサイズ指定で、* sizeof(char*) をつけて
いるので 4倍のメモリーを確保してしまいます。


> 私自身はこの手(優先度)のことを考えるのが面倒だし、
> その場で何とかなっても、自分で書いたコードにもかかわらず
> 後で見返して意味不明な状態になることが経験上わかっている ^^; ので、
> 極力手間がかからない方法を考えます。

呼び出すほうのプログラムも書いたほうがよいでしょう。
次のようにすると、一度確保した領域を使いまわすので、入力が何行あっても
realloc の回数が数回で済むはずです。
#include <stdio.h>
#include <stdlib.h>

#define ALLOC_SIZE  256

typedef struct { char *buf; size_t size, capa; } Line;

void add_character(Line *p, int c)
{
    if (p->size == p->capa) {
        p->capa += ALLOC_SIZE;
        p->buf = realloc(p->buf, p->capa);
        if (!p->buf) exit(1);
    }
    p->buf[p->size++] = c;
}

int read_line(Line *p, FILE *fp)
{
    int c;
    p->size = 0;
    while ((c = getc(fp)) != EOF && c != '\n') add_character(p, c);
    if (c == EOF && p->size == 0) return EOF;
    add_character(p, '\0');
    return p->size;
}

int main(void)
{
    Line line = { 0 };
    while (read_line(&line, stdin) != EOF) puts(line.buf);
    free(line.buf);
    return 0;
}



この投稿にコメントする

削除パスワード

No.29929

Re:実行時エラー
投稿者---ゲータレイダー(2007/03/13 00:47:01)


返信遅れてすみません。

かずま様、ぽへぇ様、アドバイスありがとうございます。




この投稿にコメントする

削除パスワード

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