对于我的项目,我必须在堆栈中存储一个堆栈。我为此使用数组,但是不允许该数组具有预定义的限制。
我不确定如何在C中无限制地创建数组。下面的代码是我的最佳尝试,并产生错误消息“数组大小具有非整数类型”。任何帮助,将不胜感激。
#include <stdio.h>
#include <stdlib.h>
int main()
{
int *g = malloc(100 *sizeof(int));
free(g);
int array[g];
printf("the array spot 0 is \n");
scanf("&i\n", array[0]);
printf("the array spot 1 is \n");
scanf("&i\n", array[1]);
printf("the array place 1 is %i and %i\n",array[0],array[1]);
return 0;
}
答案 0 :(得分:1)
首先,让我告诉您,没有“没有限制” ,毕竟您受系统上的内存(物理或虚拟)限制。
也就是说,如果您想要一个没有预定义大小的数组,并且大小是在运行时确定的,则有两个选择:
您可以考虑使用VLA (Variable length array)。对此的内存分配取决于植入,例如,gcc
在堆栈上分配VLA-因此您的大小受系统上堆栈大小的限制。
另一方面,如果您可以使用动态内存分配,则可以使用指针并使用malloc()
和realloc()
来分配和调整分配的内存大小。指针将不会是数组(反之亦然),但除此之外,没有通用的原因使其不符合您的目的。
答案 1 :(得分:0)
您误解了malloc
的操作
此行:
int *g = malloc(100 *sizeof(int));
正在手动创建大小为100的数组
因此您可以使用
g[0]
g[1]
访问数组中的元素
对于free
部分:此方法销毁(释放)您的数组,因此,当您不再需要数组时(例如,在主体的末尾),必须调用它。
答案 2 :(得分:0)
考虑以下示例:
#include <stdlib.h>
#include <limits.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
typedef struct {
size_t num; /* Number of ints in array */
size_t max; /* Number of ints allocated for */
int *array;
} intarray;
#define INTARRAY_INIT { 0, 0, NULL }
/* Discard an intarray. */
void intarray_free(intarray *iarr)
{
if (iarr) {
free(iarr->array); /* Note: free(NULL) is safe to do. */
iarr->num = 0;
iarr->max = 0;
iarr->array = NULL;
}
}
/* Ensure there is room for at least 'more' additional ints in the intarray. */
void intarray_need(intarray *iarr, const size_t more)
{
int *array;
size_t max;
/* No intarray specified? */
if (!iarr) {
fprintf(stderr, "intarray_need(): iarr == NULL!\n");
exit(EXIT_FAILURE);
}
/* Calculate size needed. */
max = iarr->num + more;
/* Array already large enough? */
if (iarr->max >= max)
return;
/* Growth policy: increase allocated size,
to avoid reallocating in too small chunks. */
if (max < 8) {
/* Always at least 8 ints. */
max = 8;
} else
if (max < 524288) {
/* Grow by 50% up to 524288. */
max = (3 * max) / 2;
} else {
/* Round up to next multiple of 262144, less 32. */
max = (max | 262143) + 262145 - 32;
}
/* Allocate. */
array = realloc(iarr->array, max * sizeof iarr->array[0]);
if (!array) {
fprintf(stderr, "intarray_need(): Out of memory; num == %zu, more == %zu, new max == %zu.\n",
iarr->num, more, max);
exit(EXIT_FAILURE);
}
iarr->max = max;
iarr->array = array;
}
/* Add one int to the intarray. */
void intarray_add(intarray *iarr, const int val)
{
/* We need room for at least one more int. */
intarray_need(iarr, 1);
/* Append. */
iarr->array[iarr->num++] = val;
}
int main(void)
{
intarray data = INTARRAY_INIT;
size_t i;
int val;
/* Parse ints from standard input. */
while (scanf("%d", &val) == 1) {
intarray_add(&data, val);
}
/* Why did the scan fail? */
if (ferror(stdin)) {
fprintf(stderr, "Error reading from standard input.\n");
exit(EXIT_FAILURE);
} else
if (feof(stdin)) {
printf("All input converted successfully.\n");
/* Fall through */
} else {
fprintf(stderr, "Warning: Could not parse all standard input.\n");
/* Fall through */
}
printf("Read %zu ints:\n", data.num);
for (i = 0; i < data.num; i++)
printf("%12d\n", data.array[i]);
intarray_free(&data);
return EXIT_SUCCESS;
}
intarray
类型是一种结构类型,它包含成员max
,num
和array
。使用INTARRAY_INIT
将其初始化为已知值。
intarray_free()
函数丢弃一个整数数组。
intarray_more()
函数很有趣。它确保为指定数量的附加int分配足够的内存。请注意,realloc(NULL, SIZE)
等效于malloc(SIZE)
;因为该结构已正确初始化(INTARRAY_INIT
),所以我们可以将其重新分配为所需的大小。
此处显示的调整大小策略只是一个示例,大致代表了我本人可能会使用的策略。它包含三个部分:最小分配大小,指数增长部分和线性增长部分。目的是,这种增长适用于小型和大型阵列,而没有巨大的缺点。真正大的线性增长部分(max = (max | 262143) + 262145 - 8;
)是一种好奇,因为它使用简单的二进制运算将其取整为2 18 = 262144的下一个倍数减去8个整数:这个想法是允许C库分配一块2 18 的倍数的块,包括其自身的开销。潜在的希望是,OS可以比其他大小更有效地做到这一点(具体来说,以2的大数的倍数进行分配)。把它当作现实生活中可能看到的例子;不是你应该做的。
虽然intarray_add()
一次只添加一个int,但您可以轻松编写另一个函数,一次添加多个int。只需记住先调用intarray_need()
,以确保有足够的内存分配给新整数。
如果您编译并运行该程序,它将从标准输入中读取整数,直到您提供非整数输入,或者遇到输入结尾(例如,从文件重定向输入)。
例如,如果您以program.exe < file.txt
或./program < file.txt
的形式运行程序,且其中file
包含
1 2
3 4 5
-6 -7
-8
9
那么输出是
All input converted successfully.
Read 9 ints:
1
2
3
4
5
-6
-7
-8
9
唯一的限制是该程序可用的内存量。
程序中还剩下一个bug:在max
中计算intarray_need()
时可能溢出,并且要重新分配的字节数(realloc()
的第二个参数)。可以检查这些参数,因为所有参数的类型均为size_t
,这是一些无符号整数类型。在C语言中,无符号整数类型使用取模算术(也就是说,就像所有计算都是取模 UINT_MAX + 1
一样)。
答案 3 :(得分:-1)
您可以初始化一个大小,然后在空间不足时将大小翻倍,并将所有元素转储到新创建的数组中。
本文讨论了如何在C语言中实现 https://codereview.stackexchange.com/questions/64423/implementing-an-arraylist