C编程中的内存复制和删除失败

时间:2016-10-03 22:58:47

标签: c memory-management memory-leaks

我正在尝试在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长整数的for循环中打印它时,它将打印正确的结果。另外,我收到了这个错误:

  

*`./test'出错:双重免费或损坏(上):0x0000000000ec4370 *   中止(核心倾销)

当我使用gnu99编译它时:

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

当我在gdb中运行它时,我只能得到__GI_raise错误。有人有想法吗?

1 个答案:

答案 0 :(得分: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);
}

让事情尽可能简单(但并不简单)几乎总是一个好主意。