我正在学习如何在C中创建动态1D数组。下面的代码尝试执行以下操作:
malloc
创建一个长度为10
的动态数组,其中包含double
类型的值。j/100
j = 0, 1,..., 9
。然后打印出来。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*)
?
答案 0 :(得分:34)
你很亲密。
在C中(至少从标准的1989版本开始),malloc
和realloc
之前的强制转换是不必要的,因为C可以将void *
类型的值转换为{{1没有演员表。这对于C ++来说不是真的,所以基于你得到的错误,听起来你正在编译这个代码为C ++而不是C.检查VS2010的文档以确定如何编译代码作为C.
以下是我编写int *
电话的首选方式:
malloc
由于表达式double *data = malloc(10 * sizeof *data);
的类型为*data
,double
相当于sizeof *data
。这也意味着,如果sizeof (double)
的类型发生变化,则无需调整malloc
来电。
对于data
调用,将结果分配给临时指针值更安全。如果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年版本的语言结束;从那时起,对语言标准进行了两次修订,引入了一些新功能,并弃用了旧功能。因此,虽然一些C编译器支持C99功能,如混合声明和代码,可变长度数组等,但VS2010不会。
答案 1 :(得分:12)
1)我编码正确吗?
清除。但是如果data = (double*)realloc(data,11*sizeof(double));
失败,realloc
会丢失对已分配内存的引用,您应该使用临时指针来保存realloc
的返回值并检查它是否为NULL
(和你一样)还应该检查malloc
)的返回值。
2)教程我发现使用malloc而不将(double *)放在前面。
在C中,malloc
返回一个void*
,它可以隐式转换为任何其他指针类型,因此不需要强制转换(并且因为可以隐藏错误的强制转换而广泛不鼓励)。 Visual Studio显然将代码编译为需要强制转换的C ++。
答案 2 :(得分:5)
在C中,您不应该转换malloc()
的返回值。
另外,在malloc()
参数中对类型进行编码是个坏主意。这是一种更好的方法:
double* data = malloc(10 * sizeof *data);