调整数组大小时,Realloc会产生无效指针错误

时间:2016-10-29 10:18:05

标签: c arrays memory

我试图给出一个随输入增加的数组的简单示例。输入是一系列数字,本系列的结尾为零。我想到的是每次读取一个新数字时增加我的数组,但由于某些原因,这似乎不起作用,因为我收到错误:

Realloc(): invalid pointer 

这是我目前的代码:

#include <stdio.h>
#include <stdlib.h>

int *resizeIntArray(int *series, int newSize) {
    int *newSeries = realloc(series, newSize * sizeof(int));
    if (newSeries == NULL) {
        printf("Error: Memory allocation failed");
        exit(-1);
    }
    return newSeries;
}

int main(int argc, char *argv[]) {
    int number;
    scanf("%d", &number);

    int *numbers;
    int size = 0;
    while (number != 0) {
       numbers = resizeIntArray(numbers, size + 1);
       printf("%d ", number);
       scanf("%d", &number);
       size++;
    }
}

4 个答案:

答案 0 :(得分:3)

您正在将未初始化的变量传递给您的函数,然后传递给realloc,它需要指向以前分配的内存的指针,或NULL

首先初始化变量:

int *numbers = NULL;

答案 1 :(得分:1)

您可以尝试这样的方法。这包括:

  • 内存检查,并附带相应的错误消息。
  • 使用malloc()realloc()分配和重新分配内存。
  • 在运行时需要时分配足够的空间。
  • 适当检查scanf()的返回值。

以下是代码:

#include <stdio.h>
#include <stdlib.h>

#define EXIT 0

void exit_if_null(void *ptr, const char *msg);

int
main(int argc, char const *argv[]) {
    int *numbers = NULL;
    int number, num_size = 1, count = 0, i;

    /* initial allocation of memory */
    numbers = malloc(num_size * sizeof(*numbers));

    /* small error checking, to be safe */
    exit_if_null(numbers, "Initial Allocation");

    /* Reading in numbers */
    printf("Enter numbers(0 to end): ");
    while (scanf("%d", &number) == 1 && number != EXIT) {

        /* valid number found, but is there space? */
        if (num_size == count) {
            num_size *= 2;

            /* resize run-time array */
            numbers = realloc(numbers, num_size * sizeof(*numbers));
            exit_if_null(numbers, "Reallocation");
        }
        numbers[count++] = number;
    }

    /* print out numbers */
    printf("Your numbers stored in array:\n");
    for (i = 0; i < count; i++) {
        printf("%d ", numbers[i]);
    }

    /* free allocated memory, very important */
    free(numbers);

    return 0;
}

/* helper function for error checking */
void
exit_if_null(void *ptr, const char *msg) {
    if (!ptr) {
        printf("Unexpected null pointer: %s\n", msg);
        exit(EXIT_FAILURE);
    }
}

答案 2 :(得分:1)

您的代码中存在多个问题:

  • 您没有将numbers初始化为NULL,因此realloc()会在第一次调用时调用未定义的行为。这导致了您观察到的问题。
  • 如果输入流不包含scanf()号,则不检查0的返回值,导致潜在的无限循环和未定义的行为。
  • 您不会将该号码存储在重新分配的数组中......
  • 你没有释放阵列(次要)。
  • 你不会在main()(次要)结束时返回0。

这里有一个更简单,更安全的版本:

#include <stdio.h>
#include <stdlib.h>

int *resizeIntArray(int *series, int newSize) {
    int *newSeries = realloc(series, newSize * sizeof(int));
    if (newSeries == NULL) {
        printf("Error: Memory allocation failed");
        exit(-1);
    }
    return newSeries;
}

int main(int argc, char *argv[]) {
    int number;
    int *numbers = NULL;
    int i, size = 0;

    /* reading the numbers */
    while (scanf("%d", &number) == 1 && number != 0) {
       numbers = resizeIntArray(numbers, size + 1);
       numbers[size++] = number;
    }
    /* printing the numbers */
    for (i = 0; i < size; i++) {
       printf("%d ", numbers[i]);
    }
    printf("\n");

    free(numbers);
    return 0;
}

答案 3 :(得分:0)

首先,您应该在重新分配之前先分配一些内存。因此,您的代码将更改为:

#include <stdio.h> 
#include <stdlib.h>
int *resizeIntArray(int *series, int newSize){
int *newSeries = realloc(series,newSize*sizeof(int));
if(newSeries == NULL){
 printf("Error: Memory allocation failed");
 exit(-1);
 }
return newSeries;
}
int main(int argc, char* argv[]) {
   int number;
   scanf("%d",&number);
   int *numbers=malloc(sizeof(int));///CHANGED
   int size = 1;///CHANGED
   while(number != 0){
   numbers = resizeIntArray(numbers,size +1);
   printf("%d ",number);
   scanf("%d",&number);
   size++;
 } 
}

但你正在做的白色是非常高效的。 realloc()函数隐藏了free()和malloc()以及最差的:memcpy()。因此,如果你在每个新项目中realloc(),那么你将会遇到一个糟糕的时间...... O(n ^ 2)。 最好的方法是分配一个内存缓冲区:

  struct vector
  {   
      int *numbers;
      size_t size;
      size_t i;
   }
   #define DEFAULTBUF 100
   int main()
   {
          struct vector v;
          v.numbers=malloc(sizeof(int)*DEFAULTBUF);
          v.size=DEFAULTBUF;
          v.i=0;
          scanf("%d",&number);
          while(number != 0 && v.numbers){
             if (v.i->=v.size)
              {   v.size+=v.size
                 v.numbers=realloc(v.numbers,sizeof(int)*v.size);
               ///i leave to you the error handling
               }
               v.i++;
              printf("%d ",number);
              scanf("%d",&number);

             }  

   }

正确使用realloc()malloc()和类似的非常重要。而且调整大小的比例也在增加。对于数据结构,我曾加倍。对于文本,我线性地进行