2

malloc 呼び出しに問題があります。問題は、この呼び出しが、プログラムで 2 回呼び出す関数にあるということです。関数の 2 番目の malloc は、この関数を 2 回目に呼び出したときにのみクラッシュします。最初のケースでは、2 番目の malloc (元々は 1 番目) がクラッシュし、2 番目のケースでは、同じ関数で後で現れる realloc がクラッシュしました。また、関数を 2 番目の前に 1 回呼び出してみましたが、(新しい) 2 番目の呼び出しでクラッシュし続けました。誰でも私を助けることができますか?これが私のコードです:

int main(int argv, char *argc[]){
    fsys = malloc(sizeof(struct ext2system)); // Global pointer var

    getsysdata();

    list_dir(fsys->root);
//  list_dir(fsys->root); // IF THIS LINE IS UNCOMMENTED, 
                          // THE PROGRAM CRASHES ON THIS CALL
                          // IF NOT, IT CRASHES ON data = get_cont(fsys->root); 

    pdir dir = malloc(sizeof(struct s_direct));
    int* data;
    int offs, i;


    data = get_cont(fsys->root);  
    offs = 0;
    for (i = 0; i < fsys->root->i_links_count + 2; ++i) {
        offs += readdirent(getblock(data[0])+offs, dir);
        printf("%.*s\n", dir->name_len, dir->name);
        if(dir->file_type==1) printf("%s\n", data);
    }

    unmap(fsys->diskmap);
    return 0;
}

void list_dir(pinode inod){
    // Lists a directory contents
    pdir dir = malloc(sizeof(struct s_direct));
    int* data;
    int offs, i;

    data = get_cont(inod);
    offs = 0;
    for (i = 0; i < inod->i_links_count + 2; ++i) {
        offs += readdirent(getblock(data[0])+offs, dir);
        printf("%.*s\n", dir->name_len, dir->name);
    }

}

int *get_cont(pinode inod){
    // Recupera contenido de los blocks de datos de un inodo
    int *cont=NULL; 
    int *idx=NULL;
    int i=0;
    int *block;

    cont = malloc(sizeof(int));
    idx  = malloc(sizeof(int)); // HERE IS WHERE THE PROGRAM CRASHES
                                // EVEN IF MALLOCS ARE SWAPPED

    while(i < inod->i_blocks && i<13) {
        // Recupera los 12 primeros bloques directamente
            realloc(cont, i*sizeof(int)); // CRASHED HERE WHEN
                                          // I DELETED ONE MALLOC

            cont[i]=inod->i_block[i];
            i++;
    }

    if(i < inod->i_blocks){
        *idx=13;
        block=(int*)getblock(inod->i_block[*idx]);
        fetchcont(block, idx, cont, inod->i_blocks, 0);
    }
    if(i < inod->i_blocks){
        block=(int*)getblock(inod->i_block[*idx]);
        fetchcont(block, idx, cont, inod->i_blocks, 1);
    }
    if(i < inod->i_blocks){
        block=(int*)getblock(inod->i_block[*idx]);
        fetchcont(block, idx, cont, inod->i_blocks, 2);
    }

    return cont;

}

アドバイスありがとう!

4

2 に答える 2

2

この部分は間違いなく問題です (短縮されたスニペット):

int i = 0;

cont = malloc(sizeof(int)); 

while(i < inod->i_blocks && i<13) {

        realloc(cont, i*sizeof(int)); 

初回iは、realloc 呼び出しの時点でゼロになります。malloc()マニュアルページには次のように書かれています:

realloc()ptr が指すメモリ ブロックのサイズを size バイトに変更します。コンテンツは、古いサイズと新しいサイズの最小値に変更されません。新しく割り当てられたメモリは初期化されません。malloc(size)ptr が NULL の場合、この呼び出しはsize のすべての値に対して ,と同等です。size がゼロに等しく、ptr が NULL でない場合、呼び出しは と同等free(ptr)です。malloc()ptr が NULL でない限り、calloc()または への以前の呼び出しによって返されたに違いありませんrealloc()。指している領域が移動された場合、afree(ptr)が実行されます。

あなたが行くので:

cont[i]=inod->i_block[i];

解放したばかりのメモリに書き込みます (または、iがゼロでない場合は、割り当てたメモリのすぐ後ろに書き込みます)。これは何でもかまいません - の内部構造を上書きしてmalloc()いる可能性があり、後で malloc または free を呼び出したときにクラッシュする可能性があります。

また、 の後はrealloc(cont, 0)contによって返されるポインターではなくなりmalloc()( を書いたかのようにfree(cont);なるため)、null にもなりません。が 1の場合、これはほぼ確実にクラッシュしiます。

あなたはおそらく次のことを意味していました:

        realloc(cont, (i+1)*sizeof(int)); 

代わりは。

于 2012-05-18T04:57:23.093 に答える
1

alloc 関数のクラッシュは、簿記データを踏んだことを意味します。getsysdata() または list_dir() コール ツリーのどこかで、malloc のデータを損傷するために、指していると思われるものの終わりをちょうど十分過ぎた位置にある不良ポインターを割り当てています。さらに悪いことに、上書きによって重要なデータが踏みにじられた可能性があります。

于 2012-05-18T04:56:34.380 に答える