31

我正在学习如何在 C 中创建动态一维数组。下面的代码尝试执行以下操作:

  1. 使用malloc,创建一个长度的动态数组10,其中包含类型的值double
  2. 将数组的每个条目设置为j/100for j = 0, 1,..., 9。然后打印出来。
  3. 使用 . 在数组末尾添加一个额外的空条目realloc
  4. 将新条目设置为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);

问题

  1. 我编码对吗?

  2. 我发现教程malloc没有放在(double*)前面。例如,

    整数 * 指针;
    指针 = malloc(2*sizeof(int));

这不适用于我在 Visual Studio 2010、Windows 7 上编译。错误消息是

void 类型的值不能分配给 类型的实体int

为什么它适用于那些教程而不适用于我?我是否正确猜测这是因为他们使用的编译器(int*)在我的示例中自动为他们填写?

4

3 回答 3

40

你很近。

在 C 中(至少从 1989 版标准开始), and 之前mallocrealloc强制转换是不必要的,因为 C 可以将类型的值转换void *int *没有强制转换的值。这不适用于 C++,因此根据您遇到的错误,听起来您正在将此代码编译为 C++ 而不是 C。查看 VS2010 的文档以确定如何将代码编译为 C。

以下是我编写malloc电话的首选风格:

double *data = malloc(10 * sizeof *data);

由于表达式的类型*datadouble,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 不支持。

于 2012-10-01T15:18:18.167 回答
12

1)我编码对吗?

大多。但是data = (double*)realloc(data,11*sizeof(double));如果失败会丢失对分配内存的引用realloc,您应该使用临时指针来保存返回值realloc并检查它是否是NULL(并且您还应该检查返回值malloc)。

2) 我发现的教程使用 malloc 而不将 (double*) 放在前面。

在 C 中,malloc返回 avoid*可以隐式转换为任何其他指针类型,因此不需要强制转换(并且由于强制转换可以隐藏错误而被广泛反对)。Visual Studio 显然将代码编译为需要强制转换的 C++。

于 2012-10-01T15:11:18.413 回答
5

在 C 中,您不应该强制转换malloc().

此外,在malloc()参数中编码类型也是一个坏主意。这是一个更好的方法:

double* data = malloc(10 * sizeof *data);
于 2012-10-01T15:09:25.817 回答