2016-10-03 83 views
0

我試圖在C中分割一個隨機生成的數組。當我試圖打印出來並檢查數據時,它總是會爲我打印最後一塊數據。我會收到一個無故障和運行時間結束:在C編程中內存複製和刪除失敗

#include <stdio.h> 
#include <stdlib.h> 
#include <math.h> 
#include <ctype.h> 
#include <string.h> 
#include <time.h> 

#define N 100 
#define CHUNK_COUNT 4 


int main(){ 
    long int * array = (long int *) malloc(sizeof(long int) *N); 
    int i; 
    int chunkSize = N/CHUNK_COUNT; 
    long int ** data = (long int **) malloc(sizeof(long int*) *CHUNK_COUNT); 
    srandom(time(NULL)); 
    for (i = 0; i< N; i++) 
    { 
     array[i] = random(); 
    } 

    for (i = 0; i<N; i++) 
    { 
     printf("%ld ",array[i]); 
    } 

    printf("\n"); 
    for (i = 0; i< CHUNK_COUNT; i++) 
    { 
     long int *subArr = (long int*) malloc(sizeof(long int)*chunkSize); 
     memcpy(subArr, &array[i*chunkSize], chunkSize*sizeof(long int)); 
     data[i] =subArr; 
     free((void *)subArr); 
    } 

    for (i = 0; i < CHUNK_COUNT; i++) 
    { 
     printf("Array %d: \n",i); 
     for(int j =0;j< chunkSize; j++) 
     { 
      if (j == 0) {printf("[ ");} 
      printf("%ld ",data[i][j]); 
      if (j==chunkSize-1) {printf("]\n");} 
     }  
    } 

    free((void *) array); 
    for (i = 0; i < CHUNK_COUNT; i++) 
    { 
     free((void*)data[i]); 
    } 
    free((void *) data); 



} 

當我調試我的代碼,我可以看到塊索引是正確的,但它總是會打印整個數據的最後一個大塊。但是,當我在for循環中打印memcpy long整數時,它會打印出正確的結果。當我使用gnu99編譯它

* Error in `./test': double free or corruption (top): 0x0000000000ec4370 * Aborted (core dumped)

gcc -std=gnu99 -o test testSplit.c -g

當我在gdb運行它,我只能得到一個__GI_raise錯誤另外,我收到此錯誤。任何人有想法?

+0

'data [i] = subArr;免費((void *)subArr);'這對你看起來不對嗎?釋放你已經保存的參考資料,並在以後使用? – kaylum

+0

@ kaylumI'm在我將它分配給'data [i]'後釋放'subArr',是否也會破壞對它的引用?那麼如何才能維持最後一塊呢?我不明白。 –

+1

如果你抄下你的房子的地址,然後摧毀你的房子是否有地址仍允許你訪問房子?訪問釋放的內存是未定義的行爲。 UB意味着結果是不可預測的(可能會崩潰,可能返回錯誤的值,有時甚至會返回正確的值!)。 – kaylum

回答

1

由於評論者已經顯示錯誤(保留地址而不是實際內容)讓我展示一個可能的解決方案。

#include <stdio.h> 
#include <stdlib.h> 
#include <math.h> 
#include <ctype.h> 
#include <string.h> 
#include <time.h> 

#define N 100 
#define CHUNK_COUNT 4 


int main() 
{ 
    // don't cast malloc() in C (you may do in O++) 
    long int *array = malloc(sizeof(long int) * N); 
    int i; 
    int chunkSize = N/CHUNK_COUNT; 
    long int **data = malloc(sizeof(long int *) * CHUNK_COUNT); 
    srand(time(NULL)); 
    for (i = 0; i < N; i++) { 
    array[i] = rand(); 
    } 

    for (i = 0; i < N; i++) { 
    printf("%ld ", array[i]); 
    } 

    printf("\n"); 
    for (i = 0; i < CHUNK_COUNT; i++) { 
    // no need for a temporary array , you can use the destination directly 
    data[i] = malloc(sizeof(long int) * chunkSize); 
    memcpy(data[i], &array[i * chunkSize], chunkSize * sizeof(long int)); 
    } 

    for (i = 0; i < CHUNK_COUNT; i++) { 
    printf("Array %d: \n", i); 
    for (int j = 0; j < chunkSize; j++) { 
     if (j == 0) { 
     printf("[ "); 
     } 
     printf("%ld ", data[i][j]); 
     if (j == chunkSize - 1) { 
     printf("]\n"); 
     } 
    } 
    } 

    free(array); 
    for (i = 0; i < CHUNK_COUNT; i++) { 
    // no need for casting here 
    free(data[i]); 
    } 
    free(data); 
} 

保持事情儘可能簡單(但並不簡單)幾乎總是一個好主意。

+0

是的,你是對的,我現在正在做同樣的事情。 –