簡體   English   中英

如果在使用 realloc 收縮后我仍然可以從另一個指針讀取內容,那么 realloc 對釋放的 memory 有什么作用?

[英]What does realloc do with the freed memory, if I can still read the content from another pointer after shrinkage with realloc?

對於表示為按四位數分組的單元格的數字:

a = 15678
a = [5678][1] //according to indexing

這是一個動態分配的 int 數組和 int 長度的結構,我嘗試將其中兩個添加到 b:

b = 0   //1 cell 
a = 15678  //2 cells

添加它們的函數非常復雜,但如果您願意,我可以發布整個代碼。 重要的:

void add(struct* a, struct* b) {
            struct* bigger;
            bigger = a; //if a has more cells
            //sum up
            ...
            *a = *bigger;
}

我想將a設置為零:

void clear(struct* a) {
      a->array = realloc(a->array, number_of_elements_in_define*sizeof(int));
      a->length = 1;
      a->array = 0;
}

但是,如果我想打印出b我得到了錯誤:

==52293== Invalid read of size 4
==52293== at 0x10CC75: print_a_number (call5.c:355)
==52293== by 0x10D027: interpreter (call5.c:397)
==52293== by 0x10D35F: game (call5.c:453)
==52293== by 0x10D521: main (call5.c:496)
==52293== Address 0x58c6804 is 4 bytes inside a block of size 34 free'd
==52293== at 0x4837D7B: realloc (vg_replace_malloc.c:826)
==52293== by 0x10CD65: clear (call5.c:367)
==52293== by 0x10D215: interpreter (call5.c:426)
==52293== by 0x10D35F: game (call5.c:453)
==52293== by 0x10D521: main (call5.c:496)
==52293== Block was alloc'd at
==52293== at 0x4837D7B: realloc (vg_replace_malloc.c:826)
==52293== by 0x10B887: add (call5.c:117)
==52293== by 0x10D115: interpreter (call5.c:406)
==52293== by 0x10D35F: game (call5.c:453)
==52293== by 0x10D521: main (call5.c:496)

但在此錯誤之后,該值被打印出來。

好像b一直在指向被釋放的memory,但是為什么可以打印呢? 如何防止這種行為或更改代碼? 我努力了:

struct copy = *bigger;
*a = copy;

但它不會改變任何東西

我會很感激你的解釋和建議。

編輯

如何在不訪問釋放的 memory 的情況下保存 b 的值? 我嘗試過使用復制,但我沒有提供任何東西。

這是修改b的代碼:

//help function
 int simple_add(int w, int m, int* p) {
     int number;
     int result = w + m + *p;
     if (result >= 10000) {
         *p = division(result);    //division by multiplication while p*i<=10000
         number = result - 10000*(*p);
     } else {
         number = result;
         *p = 0;
     }
     return number;
 }

 //problematic
 void add(numb* a, numb* b) {
     numb *big;
     numb *small;
     if (a->how_many != b->how_many) {
         small = min(a, b);  //simple min and max functions, not written for clarity
         big = max(a, b);
     } else {
         big = a;
         small = b;
     }

     int left = 0;

     int i = 0;
     while (i < small->how_many) {
         big->digits[i] = simple_add(big->digits[i], small->digits[i], &left);
         i++;
     }

     while (left != 0) {
         if (i == big->how_many) { 
             if ((size_t)i*NUM_INT*sizeof(int) >= sizeof(big->digits)) { 
                 int size;
                 if ((size_t)i*NUM_INT*sizeof(int) + 2 >= INT_MAX) size = INT_MAX-1;
                 else size = (size_t)i*NUM_INT*sizeof(int) + 2;
                 big->digits = realloc(big->digits, size);
             }
             big->digits[i++] = left;
             big->how_many++;
             pom = 0;
         } else {
             big->digits[i] = simple_add(big->digits[i], 0, &left);
             i++;
         }
     }
     *a = *big;
 }

mallocreallocfree和相關例程通常不會將 memory 添加到您的處理器或將其刪除。 他們可能會偶然做這些事情,但他們的主要工作是管理memory 的保留。

當您 go 到保齡球館並租用球道時,他們不會為您建造球道或從倉庫中帶入球道。 在過去,他們只是在周圍移動一個標記或在板上移動一些令牌或在紙上寫一個便條。 這告訴他們哪些車道正在使用中,所以他們沒有將車道分配給其他人。 你的工作是把 go 帶到你的球道並在你的球道上保齡球,即使沒有什么能阻止你在其他球道上保齡球。

Memory 管理方式相同。 當您調用malloc時,它會進行預訂並告訴您使用什么 memory。 當您調用realloc時,它會更改該預留。 當您調用free時,它會釋放該保留。

memory 不再為您保留后,您應該停止使用它。 你可以試試; 它可能還在那里。 但是你可能會干擾別人的保齡球。

對於一個不清楚的問題,我深表歉意,但我當時找不到問題的確切原因來正確發布它。

如果 b 比 a 大,我給 b 分配了一個更大的指針:

bigger = b;

因此, b指向的 memory 塊有兩個指針表示: biggerb

在我對更大的進行一些操作之后,我將bigger的內容分配給a

*a = *b;

但是,這塊 memory仍然由b指向。 如果我在b上使用 free() ,我不會完全釋放b作為指針 - 我釋放了ab指向的 memory 塊。 因此,如果我想使用a指向的內容,我會使用 freed memory - freed in free(b)

如果需要安全地復制內容,我應該進行深復制、內存復制或將 function 更改為完全在a上工作,我這次已經這樣做了。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM