(C)使用具有动态内存分配的数组

时间:2016-09-01 01:04:56

标签: c arrays memory dynamic

我想创建一个包含10个元素的简单数组。 我使用动态内存在内存中分配空间,每当我超过该数量时,它将调用realloc使其大小加倍。 每当我输入' q'它将退出循环并打印数组。

我知道我的程序充满了错误,所以请引导我进入我出错的地方。

/* Simple example of dynamic memory allocation */

/* When array reaches 10 elements, it calls
   realloc to double the memory space available */

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

#define SIZE_ARRAY 10
int main()
{
    int *a;
    int length=0,i=0,ch;


    a= calloc(SIZE_ARRAY, sizeof(int));
    if(a == NULL)
    {
        printf("Not enough space. Allocation failed.\n");
        exit(0);
    }

    printf("Fill up your array: ");

    while(1)
    {

        scanf("%d",&ch);
        if(ch == 'q')                  //possible mistake here
            break;

        a[length]=ch;
        length++;

        if(length % 10 == 0)   //when length is 10, 20, 30 ..
            {
                printf("Calling realloc to double size.\n");

                a=realloc(a, 2*SIZE_ARRAY*sizeof(int));
            }


    }

    printf("You array is: \n");
    for(;i<length;i++)
        printf("%d ",a[i]);

   return 0;
}

每当我输入&#39; q&#39;程序崩溃了。我是初学者,所以我知道我犯了一个愚蠢的错误。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:2)

你不应该每隔realloc()加倍内存,它可以变得非常大,非常快。通常只通过小块扩展内存。 realloc()也有一种讨厌的习惯,如果旧的记忆力不够长,就会使用记忆的另一部分。如果失败,则会丢失旧内存中的所有数据。这可以通过使用临时指针指向新内存并在成功分配后交换它们来避免。这需要额外指针(大多数是4或8个字节)和交换(最多只需要少量CPU周期)的成本。小心使用x86&#39; s xchg它使用锁定以防万一多个处理器非常昂贵!)

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

// would normally be some small power of two, like
// e.g.: 64 or 256
#define REALLOC_GROW 10
int main()
{
  // a needs to be NULL to avoid a first malloc()
  int *a = NULL, *cp;
  // to avoid complications allocated is int instead of size_t
  int allocated = 0, length = 0, i, ch, r;

  printf("Fill up your array: ");
  while (1) {
    // Will also do the first allocation when allocated == length
    if (allocated <= length) {
      // realloc() might choose another chunk of memory, so
      // it is safer to work on copy here, such that nothing is lost
      cp = realloc(a, (allocated + REALLOC_GROW) * sizeof(int));
      if (cp == NULL) {
        fprintf(stderr, "Malloc failed\n");
        // but we can still use the old data
        for (i = 0; i < length; i++) {
          printf("%d ", a[i]);
        }
        // that we still have the old data means that we need to
        // free that memory, too
        free(a);
        exit(EXIT_FAILURE);
      }
      a = cp;
      // don't forget to keep the amount of memory we've just allocated
      allocated += REALLOC_GROW;
    }
    // out, if user typed in anything but an integer
    if ((r = scanf("%d", &ch)) != 1) {
      break;
    }
    a[length] = ch;
    length++;
  }

  printf("Your array is: \n");
  // keep informations together, set i=0 in the loop
  for (i = 0; i < length; i++) {
    printf("%d ", a[i]);
  }
  fputc('\n', stdout);
  // clean up
  free(a);

  exit(EXIT_SUCCESS);
}

如果您使用allocated的起始值,REALLOC_GROW的值进行游戏,并使用realloc()中的乘法而不是加法,并替换if(allocated <= length)使用if(1),您可以触发无内存错误,并查看它是否仍然打印出您之前键入的内容。现在直接使用a更改realloc-on-copy,看看它是否打印数据。情况可能仍然如此,但不再保证。