2016-10-03 3 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, в котором хранятся длинные целые числа, он выводит правильные результаты. Кроме того, я получил эту ошибку:

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

Когда я использую gnu99 скомпилировать:

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

И когда я запускаю его в GDB, я мог получить только в __GI_raise ошибку. У кого-нибудь есть идеи?

+0

'data [i] = subArr; free ((void *) subArr); 'Разве это не похоже на вас? Освободить то, что вы сохранили ссылку и будете использовать позже? – kaylum

+0

@ kaylumI'm освобождая 'subArr' после того, как я назначу его' data [i] ', будет также уничтожать ссылку на это? Так почему же он будет поддерживать только последний кусок? Я не понимаю. –

+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

Да, вы правы, я делаю то же самое сейчас. –

Смежные вопросы