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时有什么区别?
非常感谢任何建议,
答案 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);