C中的动态数组 - 我对malloc和realloc的理解是否正确?

Leg*_*dre 28 c arrays malloc realloc

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

  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);
Run Code Online (Sandbox Code Playgroud)

问题

  1. 我编码是对的吗?

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

    int*指针;
    pointer = malloc(2*sizeof(int));

在Visual Studio 2010,Windows 7上,这不能为我编译.错误消息是

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

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

Joh*_*ode 34

你很亲密

在C中(至少从标准的1989版本开始),之前malloc和之前的realloc转换是不必要的,因为C可以将类型的值转换void *int *没有强制转换.对于C++ 来说不是这样,所以基于你得到的错误,听起来你正在编译这个代码为C++而不是C.检查VS2010的文档以确定如何将代码编译为C.

以下是我malloc打电话的首选方式:

double *data = malloc(10 * sizeof *data);
Run Code Online (Sandbox Code Playgroud)

由于表达式的类型*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
}
Run Code Online (Sandbox Code Playgroud)

请注意,Microsoft对C语言的支持以1989年版本的语言结束; 从那时起,对语言标准进行了两次修订,引入了一些新功能,并弃用了旧功能.因此,虽然一些C编译器支持C99功能,如混合声明和代码,可变长度数组等,但VS2010不会.


Dan*_*her 12

1)我编码这个吗?

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

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

在C中,malloc返回一个void*可以隐式转换为任何其他指针类型的东西,因此不需要强制转换(并且因为可以隐藏错误的强制转换而广泛不鼓励).Visual Studio显然将代码编译为需要强制转换的C++.


unw*_*ind 5

在C中,您不应该转换返回值malloc().

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

double* data = malloc(10 * sizeof *data);
Run Code Online (Sandbox Code Playgroud)