2

各行の先頭のバイトオフセットについてテキストファイルをスキャンするプログラムを作成しています。バイトオフセットは、longintの配列に格納されます。

テキストファイルは次のとおりです。

123456
123
123456789
12345
123
12
1
12345678
12345

テストの目的で、配列のサイズは2から始まります。これにより、Realloc関数が機能するかどうかをテストできます。

行ごとにスキャンし、各行の長さを計算して、バイトオフセットとして保存します。このループが宣言/初期化される前にすべてを想定します。

while(fgets(buffer, BUFSIZ, fptr) != NULL)
    {
        otPtr[line] = offset; 
        len = strlen(buffer)*sizeof(char);
        offset += len;
        printf("%03d %03d %03d %s", line, otPtr[line], len, buffer);
        line++;
        if(line == cursize) resize(table, &cursize);
    }

行番号==配列のサイズの場合、ループは最後の配列要素を使用しようとしているので、resizeと呼びます。resize()で、バイトオフセット値の配列の現在のサイズを2倍にします。

「realloc()」ではなく「Realloc()」を使用していることに注意してください。これは、reallocエラーをチェックし、失敗時に存在するラッパーライブラリがあるためです。

int resize(long int* table, int* cursize)
{
    long int* ptr;
    *cursize *= 2;
    printf("Reallocating to %d elements...\n", *cursize);
    ptr = (long int*)Realloc(table, (*cursize)*sizeof(long int));
    if(ptr != NULL)
        table = ptr;
}

(また、reallocを別の関数内にラップしてから、さらに別の関数にラップするのは冗長ですか?それともこの目的にはこれで問題ありませんか?またはif(ptr!= NULL)をラッパーにコーディングする必要がありますか?)

私の出力は次のようになります、

Building offset table...
Sizeof(char) in bytes: 1
001 000 008 123456
002 008 005 123
003 013 011 123456789
Reallocating to 8 elements...
004 024 007 12345
005 031 005 123
006 036 004 12
007 040 003 1
Reallocating to 16 elements...
Realloc error
Process returned 0 (0x0)   execution time : 0.031 s
Press any key to continue.

3つの列がその行の行番号//バイトオフセット//バイト長であり、最後の行がその行のテキストのプリントアウトである場合(この出力は、ループが最初にファイルをスキャンした部分からオフセットを計算します。明確でない場合は、バッファを印刷して、機能していることを確認します。)

Reallocエラーが発生するのはなぜですか?

Reallocの実装は次のとおりです。

void *Realloc(void *ptr, size_t numMembers)
{
     void *newptr;

     if ((newptr = (void *) realloc(ptr, numMembers)) == NULL)
     {
         printf("Realloc error");
         exit(1);
     }
     return newptr;
}

これが最小限のテストケースです。これまでにこれらのいずれかを書いたことはありませんが、これは「正しい」と思います。

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

void *Realloc(void *ptr, size_t numMembers);

int main(void)
{
    void resize(int** table, int* size);
    int size = 2;
    int j = 15;
    int i = 0;
    int* table;

    table = (int*)calloc(size, sizeof(int));

    while(i<j)
    {
        printf("Give number: ");
        scanf("%d", &table[i]);
        i++;
        if(i == size) resize(&table, &size);
    }
    i = 0;
    printf("Printing table...\n");
    while(i < j)
    {
        printf("%d ", table[i]);
        i++;
    }
}

void *Realloc(void *ptr, size_t numMembers)
{
     void *newptr;

     if ((newptr = (void *) realloc(ptr, numMembers)) == NULL)
     {
         printf("Realloc error");
         exit(1);
     }
     return newptr;
}

void resize(int** table, int* size)
{
        int* ptr;
        *size *= 2;
        printf("Reallocating to %d...\n", *size);
        ptr = (int*)Realloc(*table, *size*sizeof(int));
        if(ptr != NULL)
            table = ptr;
}

私が見つけたのは、サイズ= 2から始めると、早い段階でクラッシュするということです。しかし、たとえば3で大きく始めた場合、エラーを再現するのは非常に困難です。たぶん、j =より高い値を試してみたら?

4

1 に答える 1

2

reallocマニュアルページから:

...新しく割り当てられたメモリへのポインタを返します。これは、あらゆる種類の変数に適切に配置され 、ptrとは異なる場合があります。要求が失敗した場合は、NULLになります。

問題は、の戻り値を破棄していることだと思います。reallocこれは、渡したものとはまったく異なるポインタである可能性があります。

関数でresize戻り値を使用しようとしているようですが、その関数にバグがあり、結果として戻り値がフロアにスローされます。あなたresizeがする必要があります:

int resize(long int** pTable, int* cursize)
{
    long int* ptr;
    *cursize *= 2;
    printf("Reallocating to %d elements...\n", *cursize);
    ptr = (long int*)Realloc(*pTable, (*cursize)*sizeof(long int));
    if(ptr != NULL)
        *pTable = ptr;
}

そしてそれをこのように呼びます:

if (line == cursize) resize(&table, &cursize);
于 2012-05-22T23:32:03.323 に答える