C中的动态数组 – 我对malloc和realloc的理解是否正确?
我正在学习如何在C中创建动态1D数组。下面的代码尝试执行以下操作:
- 使用
malloc
,创建一个长度为10
的动态数组,它包含double
类型的值。 - 对于
j = 0, 1,..., 9
,将数组的每个条目设置为j/100
。 然后打印出来。 - 使用
realloc
在数组末尾添加一个额外的空条目。 - 将新条目设置为
j/100
并再次打印出每个条目。
测试:
double* data = (double*)malloc(10*sizeof(double)); for (j=0;j<10;j++) { data[j]= ((double)j)/100; printf("%g, ",data[j]); } printf("\n"); data = (double*)realloc(data,11*sizeof(double)); for (j=0;j<11;j++) { if (j == 10){ data[j]= ((double)j)/100; } printf("%g, ",data[j]); } free((void*) data);
问题
-
我编码正确吗?
-
教程我发现使用
malloc
而不将(double*)
放在前面。 例如,int *指针;
pointer = malloc(2 * sizeof(int));
在Visual Studio 2010,Windows 7上,这不能为我编译。错误消息是
void类型的值不能分配给
int
类型的实体。
为什么它适用于那些教程而不适合我? 我是否正确地猜测这是因为他们使用的编译器在我的示例中自动为它们填充(int*)
?
你很亲密
在C中(至少从标准的1989版本开始), malloc
和realloc
之前的malloc
转换是不必要的,因为C可以在没有realloc
转换的情况下将void *
类型的值转换为int *
。 这对于C ++来说并非如此,因此基于您所获得的错误,听起来您将此代码编译为C ++而不是C.请查看VS2010的文档以确定如何将代码编译为C.
以下是我编写malloc
调用的首选样式:
double *data = malloc(10 * sizeof *data);
由于表达式*data
的类型是double
,因此sizeof *data
等于sizeof (double)
。 这也意味着如果data
类型发生变化,您不必调整malloc
调用。
对于realloc
调用,将结果分配给临时指针值更安全。 如果realloc
无法扩展缓冲区,则返回NULL,因此写入更安全
double *tmp; ... tmp = realloc(data, 11 * sizeof *data); if (!tmp) { // could not resize data; handle as appropriate } else { data = tmp; // process extended buffer }
请注意,Microsoft对C语言的支持以1989年版本的语言结束; 从那以后,对语言标准进行了两次修订,引入了一些新function,并弃用了旧function。 因此,虽然一些C编译器支持C99function,如混合声明和代码,可变长度数组等,但VS2010不会。
1)我编码是对的吗?
大多。 但是data = (double*)realloc(data,11*sizeof(double));
如果realloc
失败,则丢失对分配的内存的引用,您应该使用临时指针来保存realloc
的返回值并检查它是否为NULL
(并且您还应该检查malloc
的返回值)。
2)教程我发现使用malloc而不将(double *)放在前面。
在C中, malloc
返回一个void*
,它可以隐式转换为任何其他指针类型,因此不需要强制转换(并且因为可以隐藏错误的强制转换而广泛不鼓励)。 Visual Studio显然将代码编译为需要强制转换的C ++。
在C中,您不应该转换malloc()
的返回值。
此外,在malloc()
参数中编码类型是一个坏主意。 这是一种更好的方法:
double* data = malloc(10 * sizeof *data);