【发布时间】:2018-11-29 06:54:28
【问题描述】:
如何让用户选择一个数字,比如 n,然后创建一个大小为 n 的数组?
我可以说int a[]=malloc (n*sizeof(int))吗?
【问题讨论】:
-
我会小心让用户分配任意大小的数组。除非他们被信任,即你。巨大的分配可能存在稳定性问题
如何让用户选择一个数字,比如 n,然后创建一个大小为 n 的数组?
我可以说int a[]=malloc (n*sizeof(int))吗?
【问题讨论】:
有两种方法可以做到这一点。如果数组很小,那么你可以使用变长数组
/* Valid in C99 and later */
int n;
scanf("%d", &n);
int a[n];
这将在堆栈上分配内存。另一种方法是您可以使用动态内存分配,它将在堆上分配内存
int *a = malloc(n*sizeof(int));
【讨论】:
你的想法几乎是正确的:
int a[] = malloc(n*sizeof(int));
使用malloc 是正确的方法。
但是您不能将返回的地址分配给数组。
您必须改用指针变量:
int *a = malloc(n*sizeof(int));
【讨论】:
是的,如果你想在运行时设置数组的大小。
那么你应该去动态内存分配(malloc/calloc)。
int a[]=malloc (n*sizeof(int));//this not possible.
int *a =malloc (n*sizeof(int)); // this is possible.
【讨论】:
分配内存以创建数组有两种基本方法,其中数组的大小被确定为输入:
第一个是, 在内存的“堆栈”段中为数组分配内存,其中数组的大小作为输入ant,然后定义该特定大小的数组并相应地授予内存。
int n;
scanf("%d",&n); //scanning the size
int arr[n]; //declaring the array of that particular size here
第二个是, 在内存的“堆”段中分配所需的内存。它是在运行时分配的内存(程序的执行) 因此,另一种声明大小由用户定义的数组的方法是
int n,*arr;
scanf("%d",&n);
arr=malloc(n*sizeof(int)); //malloc function provides a contiguous space
或
arr=calloc(n,sizeof(int)); //calloc function is similar,initializes as 0
要使用这两个函数,请确保包含 stdlib.h。
【讨论】:
void-pointers。只需删除那些 (int*)。
可变长度数组 (VLA) 在 C99 中添加到 C 中,但在 C11 中变为可选。不过,它们仍然得到广泛支持。这是在运行时定义具有用户选择大小的数组的最简单方法。
除了 VLA 可能并非在所有平台上都可用之外,它们还可能在分配失败时静默失败。这是malloc()在正确使用时避免的缺点。
您不能在 C 中分配给数组,而是需要将 malloc() 返回的值存储在指针中。请注意,当分配失败时,malloc() 返回NULL,允许代码检查失败并相应地继续。实际分配可能如下所示:
int *a_dyn = malloc(sizeof *a_dyn * arr_sz);
这是调用malloc() 的惯用方式。请注意有no need to cast the result of malloc(),并注意sizeof 的操作数不是显式类型,而是涉及a_dyn 的表达式。 sizeof 运算符使用表达式*a_dyn 的type,它实际上是int(没有取消引用)。与使用显式类型进行编码相比,在程序生命周期中类型发生变化时,这更不容易出错并且更容易维护。还要注意sizeof 表达式出现在arr_sz 之前。这是一个很好的做法:有时您可能会遇到这样的电话:
int *arr = malloc(sizeof *arr * nrows * ncols);
首先放置sizeof 会强制使用size_t 值完成乘法,有助于避免乘法中的溢出问题。
不要忘记在不再需要时释放使用malloc() 分配的任何内存,避免内存泄漏。
无论您使用 VLA 还是 malloc(),您都必须在使用前验证用户输入以避免未定义的行为。尝试分配非正数大小的数组会导致未定义的行为,而尝试分配过多内存将导致分配失败。
下面是一个示例程序,说明了所有这些:
#include <stdio.h>
#include <stdlib.h>
#define ARR_MAX 1024 // some sensible maximum array size
int main(void)
{
int arr_sz;
int ret_val;
/* validate user input */
do {
printf("Enter array size: ");
ret_val = scanf("%d", &arr_sz);
} while (ret_val != 1 || arr_sz < 1 || arr_sz > ARR_MAX);
/* use a VLA */
int a_vla[arr_sz];
for (int i = 0; i < arr_sz; i++) {
a_vla[i] = i;
printf("%d ", a_vla[i]);
}
putchar('\n');
/* use malloc() */
int *a_dyn = malloc(sizeof *a_dyn * arr_sz);
if (a_dyn == NULL) { // malloc failure?
fprintf(stderr, "Unable to allocate memory\n");
} else { // malloc success
for (int i = 0; i < arr_sz; i++) {
a_dyn[i] = i;
printf("%d ", a_dyn[i]);
}
putchar('\n');
}
/* avoid memory leaks */
free(a_dyn);
return 0;
}
【讨论】: