在运行时以标准C(不在C99中)声明数组的大小

时间:2014-05-18 09:08:35

标签: c dynamic malloc

数组需要在编译时定义大小。是否有可能使用malloc或其他任何内容在运行时定义数组的大小?

6 个答案:

答案 0 :(得分:6)

这是完全可能的并且很常见。适合工作的工具是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中创建动态数组。请务必在使用free()(或malloc())预留的内存上致电calloc()

答案 1 :(得分:1)

要在编译时定义数组的大小,您可以使用预处理器宏来创建可在一个位置更新的常量表达式:

#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);

答案 2 :(得分:1)

VLA是一个c99功能..无论你想叫它,都不能在ANSI C / C89 / C90中使用。

但是VLA引入了我不喜欢的复杂性,因此在std C中执行以下操作非常常见:(创建一个连续的内存块,就像堆上的C数组一样,然后通过它访问它取消引用指针,或直接使用数组语法,两者都是等效的,然后确定

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);
}

答案 3 :(得分:1)

正如其他答案指定的那样,您可以使用malloc函数创建mxn矩阵 1 int秒。

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 请注意,虽然您似乎正在创建一个数组,但数组和指针是两种不同的类型。 Arrays are not pointers and pointers are not arrays

答案 4 :(得分:0)

使用alloca可以实现动态大小的数组的等效实现。此函数在当前函数的堆栈帧中分配系统堆栈上的空间,就好像它是局部变量一样。所以,例如:

void fun(int i) {
   int a[i];
   ...
}

将被实施为:

void fun(int i) {
   int *a = alloca(i * sizeof(int));
   ...
}

在函数返回时“释放”已分配的空间。但是,alloca不符合POSIX。

答案 5 :(得分:0)

您可以根据自己的要求使用calloc , malloc or realloc。它们清楚地解释了here

  

malloc函数分配n个字节的内存,适合于任何类型的存储。此指针适用于传递给free,释放它或realloc,这会改变它的大小(并可能将其移动到不同的位置)。 calloc分配nmemb * size字节,就像用malloc一样,并将它们设置为所有位零   应该注意,所有位零不一定是有效的空指针或浮点0,因此不能依赖calloc来正确初始化所有数据类型。

以下是一些代码示例

#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);    
相关问题