【问题标题】:Memory copy and delete failed in C programmingC编程中的内存复制和删除失败
【发布时间】:2016-10-03 22:58:47
【问题描述】:

我正在尝试在 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);



}

当我调试我的代码时,我可以看到块索引是正确的,但它总是会打印整个数据的最后一个块。但是,当我在我 memcpy 长整数的 for 循环中打印它时,它将打印正确的结果。另外,我收到了这个错误:

* `./test' 中的错误:双重释放或损坏(顶部):0x0000000000ec4370 * 中止(核心转储)

当我使用 gnu99 编译时:

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

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

【问题讨论】:

  • data[i] =subArr; free((void *)subArr); 你不觉得有问题吗?释放您已保存参考并稍后使用的内容?
  • @kaylum 在我将subArr 分配给data[i] 之后,我正在释放它,这也会破坏对它的引用吗?那么为什么它只会保留最后一个块呢?我不明白。
  • 如果你抄下你家的地址然后毁掉你的房子,拥有地址是否仍然允许你进入房子?访问释放的内存是未定义的行为。 UB 意味着结果是不可预测的(可能崩溃,可能返回错误值,有时甚至可能返回正确值!)。
  • 我明白你的意思

标签: c memory-management memory-leaks


【解决方案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);
}

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-03-16
    • 2020-11-06
    • 1970-01-01
    • 2019-06-22
    • 2015-04-03
    • 2012-03-06
    • 1970-01-01
    • 2018-03-22
    相关资源
    最近更新 更多