1

Linux の vanguard/gdb で検出されたが、Windows cygwin 環境では完全に実行されるコードで見つけられないヒープ割り当てエラーがあります。Linux のヒープ割り当てが Windows よりも厳しくなる可能性があることは理解していますが、問題/可能な修正を発見する応答が本当に必要です。また、C で malloc を型キャストするべきではないことも認識していますが、これは習慣の力であり、問​​題が発生するのを変えるものではありません。私のプログラムは実際には Linux と Windows の両方でエラーなしでコンパイルされますが、Linux で実行すると恐ろしい結果が得られます。

malloc.c:3074: sYSMALLOc: アサーション `(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)' が失敗しました。中止しました

レビュー用のエラーとして指摘されている私のコードからの添付スニペット:

/* Main */

int main(int argc, char * argv[]) {

    FILE *pFile;  
    unsigned char *buffer;  
    long int lSize;  

    pFile = fopen ( argv[1] , "r" );
    if (pFile==NULL) {fputs ("File error on arg[1]",stderr); return 1;}

    fseek (pFile , 0 , SEEK_END);
    lSize = ftell (pFile);
    rewind (pFile);

    buffer = (char*) malloc(sizeof(char) * lSize+1);
    if (buffer == NULL) {fputs ("Memory error",stderr); return 2;}

    bitpair * ppairs = (bitpair *) malloc(sizeof(bitpair) * (lSize+1));

    //line 51 below
    calcpair(ppairs, (lSize+1));

    /* irrelevant stuff */

    fclose(pFile);
    free(buffer);
    free(ppairs);  
}

typedef struct {  
long unsigned int a;  //not actual variable names...  Yes I need them to be long unsigned  
long unsigned int b;  
long unsigned int c;  
long unsigned int d;  
long unsigned int e;  
} bitpair;  

void calcpair(bitpair * ppairs, long int bits);

void calcPairs(bitpair * ppairs, long int bits) {

    long int i, top, bot, var_1, var_2;
    int count = 0;

    for(i = 0; i < bits; i++) {

        top = 0;

        ppairs[top].e = 1;

        do {
            bot = count;
            count++;
        } while(ppairs[bot].e != 0);

        ppairs[bot].e = 1;

        var_1 = bot;
        var_2 = top;

        bitpair * bp = &ppairs[var_2];
        bp->a = var_2;
        bp->b = var_1;
        bp->c = i;

        bp = &ppairs[var_1];
        bp->a = var_2;
        bp->b = var_1;
        bp->c = i;

    }

    return;
}

gdb レポート: free(): 無効なポインター: 0x0000000000603290 *

valgrind は、「VALGRIND INTERNAL ERROR」シグナル 11 (SIGSEGV) が原因で、終了する前に次のメッセージを 5 回報告します:
Invalid read of size 8
==2727== at 0x401043: calcPairs (in /home/user/Documents/5-3/ubuntu) test/main)
==2727== by 0x400C9A: main (main.c:51)
==2727== アドレス 0x5a607a0 は、スタック、malloc、または (最近) 解放されていません

4

4 に答える 4

1

配列オーバーランのように見える

このループが ppair 配列の末尾をオーバーランするのを妨げているものは何もありません。

    do { 
        bot = count; 
        count++; 
    } while(ppairs[bot].e != 0); 

特に、この行は終端のゼロを上書きするため:

ppairs[bot].e = 1;

代わりにこれを試してください:

    do { 
        bot = count; 
        count++; 
    } while((bot < bits) && (ppairs[bot].e != 0)); 

あなたの、トム

于 2010-05-08T00:13:40.933 に答える
1

ftell は -1 を返し、malloc は 0 バイトの割り当てを要求されるのを好みません。malloc(0) の動作は、C では実装に依存します。

于 2010-05-04T16:09:00.333 に答える
1

malloc が事前にゼロ化されたメモリを返すことを期待しているようです。

    do {
        bot = count;
        count++;
    } while(ppairs[bot].e != 0);

ゼロ化された ppairs[bot].e を見つけることなく、簡単に ppairs の最後に到達できます。

メモリを返す前にメモリをクリアする malloc の代わりに calloc を使用します。

bitpair * ppairs = (bitpair *) calloc(sizeof(bitpair) * (lSize+1));
于 2010-05-04T17:09:49.843 に答える
0

neverへの 2 番目の呼び出しでmallocは、戻り値がチェックされません。次のように、最初のもののように見えるように変更します。

bitpair * ppairs = (bitpair *) malloc(sizeof(bitpair) * (lSize+1));
if (ppairs == NULL) {fputs ("Memory error",stderr); free(buffer); return 3;}

また、引数には (定義は実装に依存する) が必要であるmallocことを忘れないでください。size_tに渡すときにa をオーバーフローしていない(sizeof(bitpair) * (lSize+1))ことを確認してください(が として定義されている場合、が a であるため、問題が発生する可能性があります)。mallocsize_tsize_tunsigned intlSizelong

于 2010-05-04T16:57:48.347 に答える