0

パターンのすべての出現を検索し、パターンに一致するファイル内のオフセットの配列を返す関数を作成しようとしています。realloc を使用して、返された配列を動的に拡張したいのですが、sYSMALLOC アサーション エラーが発生します。別の検索パターンを使用すると、無効な次のサイズ エラーが発生することがあります。私のマシンにはまだ valgrind がありません (デバッグ フラグを使用して glibc を再構築する必要があります)。これはとても単純な問題のように思えます。私はこのポインターに 2 回だけ触れます。sizeof(char) が 1 であることはわかっており、realloc ステートメントに含める必要はありません。

問題のある関数のコードを次に示します。

unsigned long long* searchBytes(FILE* fp, char* byteString, char* searchType, unsigned   long long fileSize)
{
if (fp == NULL)
    return NULL;

unsigned long long* foundBytes = NULL;
long numBytes = 0;

// make some memory for the array of found bytes
if (strcmp(searchType, "ascii") == 0)
{
    numBytes = strlen(byteString);
    //foundBytes = realloc(NULL, numBytes * sizeof(char));
}
else
{
    // TODO strip the spaces from the string and handle hex searches
    printf("hex-search not implemented yet.\n");
    return NULL;
}

// loop over all the bytes in the file looking for this ascii pattern
unsigned long long currentOffset = 0;
unsigned long long origOffset = 0;
unsigned long long m = 0;
foundWords = 0;
char* possibleWord = malloc(numBytes * sizeof(char));

do
{
    fseek(fp, currentOffset, SEEK_SET);
    unsigned long long i;
    int n = 0;
    int failed = 0;
    origOffset = currentOffset;

    for(i=currentOffset; i<currentOffset+numBytes; i++)
    {
        possibleWord[n] = fgetc(fp);
        n++;
    }
    //printf("possibleWord: %s\n", possibleWord);

    // is this our word? use strstr just in case
    char* found = strstr((const char*) byteString, (const char*) possibleWord);
    if (found)
    {
        foundWords++;
        // make a bigger spot for it
        printf("allocating %ld bytes to add word %d to list...\n", (numBytes*foundWords) * sizeof(char), foundWords);
        unsigned long long* p = realloc(foundBytes, (numBytes*foundWords) * sizeof(char));
        if (p)
        {
            foundBytes = p;

            for (i = origOffset; i<origOffset+numBytes; i++)
            {
                foundBytes[m] = i;
                //printf("added offset %llu to foundBytes[%llu]\n", i, m);
                m++;
            }

        }
        else
        {
            return NULL;
        }

    }
    else
    {
        failed = 1;
    }

    if (failed == 0)
    {
        currentOffset += numBytes;
        //printf("Yay! moving forward %ld bytes.\n", numBytes);
    }
    else
    {
        currentOffset++;
    }   
}
while (currentOffset < fileSize);

if (foundWords > 0)
{
    //printf("returning foundBytes!\n");

    //unsigned long long z;
    //for (z=0; z<foundWords*numBytes; z++)
    //  printf("%llu\n", foundBytes[z]);
    //printf("...\n");
    return foundBytes;
}
//printf("returning NULL\n");
return NULL;
}

検索パターンとして「root」を使用して /etc/passwd で実行した場合:

allocating 4 bytes to add word 1 to list...
allocating 8 bytes to add word 2 to list...
*** glibc detected *** ./chex3: realloc(): invalid next size: 0x0000000001a59270 ***

または /etc/passwd で「daemon」を検索パターンとして使用:

allocating 6 bytes to add word 1 to list...
allocating 12 bytes to add word 2 to list...
chex3: malloc.c:2451: sYSMALLOc: Assertion `(old_top == (((mbinptr) (((char *) &((av)->bins[((1) - 1) * 2])) - __builtin_offsetof (struct malloc_chunk, fd)))) && old_size == 0) || ((unsigned long) (old_size) >= (unsigned long)((((__builtin_offsetof (struct malloc_chunk, fd_nextsize))+((2 * (sizeof(size_t))) - 1)) & ~((2 * (sizeof(size_t))) - 1))) && ((old_top)->size & 0x1) && ((unsigned long)old_end & pagemask) == 0)' failed.

誰かがこれを見て、問題がないように見えるかどうかを確認できますか? ありがとう!私は学ぼうとしている初心者です:)

4

1 に答える 1

0

解決策は、foundBytes を使用して p を先頭に宣言し、realloc 行を次のように変更することでした。

p = realloc(foundBytes, (numBytes*foundWords) * sizeof(*p));

なぜこれが必要なのかよくわからないことを認めなければなりません。この方法で十分すぎるほど多くを割り当てているようです。(3 文字の検索パターンの場合、毎回 3 ではなく 24 バイトを追加します)

于 2012-12-18T16:57:22.043 に答える