c - 重新分配无效的旧大小

标签 c pointers malloc realloc

免责声明:这是家庭作业。我正在尝试,不期望或不希望任何人为我做这件事。只要指出一些我出错的地方(呵呵),我们将不胜感激。

作业要求我创建一个包含 10 个元素的 int* 数组,然后尝试向其中插入一百万个整数。每次插入都会检查数组是否需要调整大小,如果需要,我会增加它的大小,以便它可以再容纳一个元素。

当我插入 10,000 个元素时,它工作正常,但如果我尝试 100,000 个元素,则会出现以下错误:

*** glibc detected *** ./set2: realloc(): invalid old size: 0x00000000024dc010 ***

这是我正在运行的代码。我已经对其进行了评论,因此很容易阅读。

void main()
{
    //begin with a size of 10
    int currentsize = 10;
    int* arr = malloc(currentsize * sizeof(int));       
    int i;

    //initalize with all elements set to INT_MAX
    for(i = 0; i < currentsize; i++) {
        arr[i] = INT_MAX;
    }


    // insert random elements
    for(i = 0; i < 100000; i++) {
        currentsize = add(rand() % 100,arr,currentsize);
    }

    free(arr);
}

/*
    Method resizes array if needed, and returns the new size of the array
    Also inserts the element into the array
*/
int add(int x, int* arr, int size)
{
    //find the first available location 
    int newSize = size;
    int i;
    for(i = 0; i < size; i++) {
        if (arr[i] == INT_MAX)
            break;
    }

    if (i >= size) {
        //need to realloc
        newSize++;
        arr = realloc(arr, newSize * sizeof(int) );     
    }

    arr[i] = x;

    return newSize;
}

最佳答案

该错误可能是因为您在函数 add 中正确使用了 realloc 更改了 arr,但是当 add 返回时这个修改的值丢失了。因此,下一次调用 add 将收到旧的、现在错误的值。

此外,我不明白为什么您使用 for 循环进行搜索。您知道要在最后一个元素添加,那么为什么要搜索呢?只需重新分配数组并将新值插入新槽即可。

顺便说一句,我很确定您的老师正在试图让您了解为每个成员重新分配会导致渐近运行时问题。大多数 realloc 实现都会使用此算法进行大量复制。这就是为什么实际程序将数组大小增加一个大于 1(通常为 1.5 或 2)的因子,而不是固定的量。

通常的习惯用法是将可变大小数组抽象为结构体:

typedef struct array_s {
  int *elts;
  int size;
} VARIABLE_ARRAY;

void init(VARIABLE_ARRAY *a)
{
  a->size = 10;
  a->elts = malloc(a->size * sizeof a->elts[0]);
  // CHECK FOR NULL RETURN FROM malloc() HERE
}

void ensure_size(VARIABLE_ARRAY *a, size_t size) 
{
  if (a->size < size) {

    // RESET size HERE TO INCREASE BY FACTOR OF OLD SIZE
    // size = 2 * a->size;

    a->elts = realloc(size * sizeof a->elts[0]);
    a->size = size;

    // CHECK FOR NULL RETURN FROM realloc() HERE
  }
}

// Set the i'th position of array a. If there wasn't
// enough space, expand the array so there is.
void set(VARIABLE_ARRAY *a, int i, int val)
{
  ensure_size(a, i + 1);
  a->elts[i] = val;
}

void test(void)
{
  VARIABLE_ARRAY a;

  init(&a);

  for (int i = 0; i < 100000; i++) {
    set(&a, i, rand());
  }

  ...

}

关于c - 重新分配无效的旧大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36962562/

相关文章:

c - gets() 不起作用

android - 指针取消引用以访问另一个文件中的数组

c - 为什么我的列表只返回最近添加的元素?

c - 请用 C 解释这个 *char malloc/realloc/free 行为

c++ - Windows 应用程序的堆大小

c - 初始化动态分配的整数

c - 仅将指轮数据发送到串行一次

C:如何返回主要用法?

c - 从写入的文件中读取一行整数? C语言编程

c - 数组给出垃圾值