初始化分配数组的大小

时间:2010-08-19 02:53:58

标签: c sizeof

gcc 4.4.3 c89

我想知道为什么在初始化指向char的指针数组时无法分配数组的大小。

我收到以下错误:

variable-sized object may not be initialized

这没关系。但是,sizeof将返回4个字节,因为char *的大小为4个字节。哪个不好,因为它不是我想要的实际尺寸。

void inc_array(const char * const src, size_t size)
{
    /* Array of pointers */
    char *dest[sizeof(src)] = {0};
}

但是,我想要做的就是传递实际大小并使用它来初始化数组的长度。

void inc_array(const char * const src, size_t size)
{
    /* Array of pointers */
    char *dest[size] = {0};
}

当sizeof返回size_t并且我传递size_t时有什么区别?

非常感谢任何建议,

4 个答案:

答案 0 :(得分:4)

使用malloc分配动态大小的数组。

您还必须确保malloc ed数据最终为free d。

答案 1 :(得分:4)

在C89中你根本不能这样做 - 在C99之前不支持可变大小的数组。数组大小必须是编译时常量。你想要这样的东西:

void inc_array(const char * const src, size_t size) {
    char ** dest = calloc(size, sizeof(char*));
    /* do stuff with dest here! */
}

我不确定你想要一个指针数组。我原本期望以下内容:

void inc_array(const char * const src, size_t size) {
    char *dest = calloc(size, sizeof(char));
    memcpy(&dest[0], &src[0], size);
    /* do stuff with dest */
    free(dest);
}

修改: 我忘了回答你问题的第二部分

区别在于sizeof(src)是编译时表达式(IIRC),因为它正在计算类型的大小。在这种情况下,它与sizeof(char*)相同,在您的平台上可能是32位。但是,size中的char *dest[size]无法静态确定。两者都是size_t值,但C89要求静态分配的数组中的元素数量在编译时是可确定的。这就是你必须采用动态分配的原因。

答案 2 :(得分:2)

正如错误消息所示,无法初始化可变长度数组 - 也就是问题是= { 0 }部分。您仍然可以使用可变长度数组 - 您只需要显式初始化它:

void inc_array(const char * const src, size_t size)
{
    /* Array of pointers */
    size_t i;
    char *dest[size];

    for (i = 0; i < size; i++)
        dest[i] = 0;
}

答案 3 :(得分:1)

sizeof运算符无法正常工作的原因是,当您将数组传递给函数时,数组会“衰减”到指针:

int array[5];
printf("%d\n", sizeof(array) / sizeof(int)); /* prints 5 */

/* ... */

void some_function(int array[])
{
  printf("%d\n", sizeof(array) / sizeof(int)); /* prints 1, no matter what */
}

至于定义数组,在旧版本的C中,不允许使用可变长度数组(请注意,Visual Studio仍然实现了旧版本的C)。你必须指定一个恒定的大小:

const size_t some_size = 22;
size_t some_other_size = 5;
int array1[5]; /* okay */
int array2[some_size]; /* okay */
int array3[some_other_size]; /* not okay - not const */

较新版本的C(实现C99标准的编译器)允许您指定可变大小:

size_t some_other_size = 5;
int array3[some_other_size]; /* okay - VLA */

作为旁注, C ++ 标准的任何版本都不包含对VLA的支持。但是,有些C ++编译器已经实现了自己的扩展(参见Groxx的评论)。

如果要在不支持VLA的C编译器中分配可变数量的连续内存,则必须使用malloc和free,如kbrimington建议的那样:

size_t size = 5;
int* array = (int*)malloc(sizeof(int) * size);
/* use array */
free(array);