我想创建一个包含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;程序崩溃了。我是初学者,所以我知道我犯了一个愚蠢的错误。任何帮助将不胜感激。
答案 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,看看它是否打印数据。情况可能仍然如此,但不再保证。