数组需要在编译时定义大小。是否有可能在运行时使用malloc
或其他东西来定义数组的大小?
这是完全可能的,也是非常常见的。合适的工具是malloc()
函数。这允许您在运行时动态创建任何大小的数组。一个例子是在运行时创建一个由用户指定大小的数组。
int main(int argc, const char **argv)
{
printf("How long should the dynamic array be?");
int length;
scanf("%d", &length);
// dynamically create the array with malloc
int *array = malloc(sizeof(*array) * length);
return 0;
}
这个数组(指向int
的指针)可以像任何其他数组一样使用,通过[]
操作符访问其值。
int fifthValue = array[4]; // assumes array was malloc()'d with at least 5 mem slots.
当你用完这个动态创建的数组后,使用free()
函数把它的内存还给程序。
free(arr);
malloc()
的第二个替代方案是calloc()
函数。因为malloc()
返回的内存块并不总是初始化的,所以它可能包含垃圾数据。如果不希望这样,可以使用calloc()
函数。calloc()
将为您初始化返回到0
的内存中的所有元素。对calloc()
的调用与对malloc()
的调用略有不同。
int main(int argc, const char **argv)
{
printf("How long should the dynamic array be?");
int length;
scanf("%d", &length);
// dynamically create the array with calloc and initialize it to 0
int *array = calloc(length, sizeof(*array));
return 0;
}
综上所述,malloc()
和free()
函数非常适合在C
中创建动态数组。请记住,在malloc()
(或calloc()
)保留的内存中始终调用free()
。
要定义在编译时数组的大小,您可以使用预处理器宏,例如,创建一个可以在一个位置更新的常量表达式:
#define ARR_LEN 50
char array_one[ARR_LEN];
char array_two[ARR_LEN];
如果您想在运行时确定实际长度,那么您必须使用动态内存分配:
int arr_len = <user-input>;
char *array_one = (char*)malloc(sizeof(char) * arr_len);
// use the array
free(array_one);
VLA是c99的一个特性。并且在ANSI C/C89/C90中不可用,不管你怎么称呼它
但是VLA引入了我不喜欢的复杂性,所以在std C中,通常会这样做:(创建一个连续的内存块,就像堆上的C数组一样,然后通过解引用指针来访问它,或者直接使用数组语法,两者都是等效的,ok)
typedef struct
{
int a;
int b;
}MyStruct;
int main(int argc, const char * argv[])
{
size_t numberOfElements = 5;
//this will create a buffer numberOfElements * sizeof(MyStruct) in size and init each byte to 0;
MyStruct * myAlmostArray = calloc(sizeof(MyStruct),numberOfElements);
//do Stuff
int i;
for(i=0;i<numberOfElements;i++)
{
//gets the array (not needed in this example)
MyStruct s = myAlmostArray[i];
s.a = 3;
s.b = i;
//write the stack array back to the heap allocated psuedo array
myAlmostArray[i] = s;
//or slightly different example where you mutate the heap memory directly
myAlmostArray[i].a = 3;
myAlmostArray[i].b = i;
//or the same thing written differently
MyStruct * m = myAlmostArray + i;
m->a = 3;
m->b = i;
}
// free the memory
free(myAlmostArray);
}
正如其他答案所指定的那样,您可以使用malloc
函数来创建mxn
矩阵1 int
s
int **matrix = malloc(m * sizeof(int *));
for(int i = 0; i < n; i++)
matrix[i] = malloc(n * sizeof(int));
另一种方法是,虽然它不是动态的,也不是有效的,但却给人一种动态的印象:
#define m 100
#define n 100
//...
int main()
{
int arr[m][n], row, col;
scanf("%d %d", row, col);
arr[row][col];
//...
}
1注意,虽然看起来你是在创建一个数组,但数组和指针是两种不同的类型。数组不是指针,指针也不是数组
您可以根据您的需求使用calloc , malloc or realloc
。
malloc函数分配n个字节的内存,适合于任何类型的存储。这个指针适合传递给free(释放它)或realloc(改变它的大小(并可能将它移动到不同的位置)。与malloc一样,Calloc分配nmemb*size字节,并将它们设置为所有位为0。
应该注意的是,所有位的0不一定是有效的空指针或浮点0,因此不能依赖callloc来正确初始化所有数据类型。
下面是一些代码示例
#include<stdlib.h>
/*
some code
*/
n = some_calculation() ; // array size generated at runtime
// data_type is the type of the array eg. int or struct
//using calloc ,it will set allocated values to zero or NULL as per their data_type
data_type *array = calloc(n,sizeof(data_type)) ;
// using malloc , it will only allocate adresses, they may contain garbage values
data_type *array = (data_type *)malloc(n);
// using realloc
array = (data_type *) realloc(array, new_n);
// after you have used your array , you can free the memory allocated
free(array);
可以使用alloca
实现动态大小数组的等效实现。这个函数在当前函数的堆栈帧中的系统堆栈上分配空间,就好像它是一个局部变量一样。例如:
void fun(int i) {
int a[i];
...
}
将被实现为:
void fun(int i) {
int *a = alloca(i * sizeof(int));
...
}
分配的空间在函数返回时被"释放"。然而,alloca
不符合POSIX。