这是从函数返回结构数组的正确方法吗?

Mat*_*att 5 c malloc struct memory-management

正如标题所说(并建议),我是C的新手,我试图从函数中返回任意大小的结构数组.我选择使用malloc互联网上比我更聪明的人,指出除非我分配给堆,否则数组将在points_on_circle完成执行时被销毁,并且将返回无用的指针.

我提出的代码曾经工作,但现在我在代码中越来越多地调用函数,我遇到了运行时错误./main: free(): invalid next size (normal): 0x0a00e380.我猜这是由我的黑客一起实现的数组/指针.

我还没有打电话free,因为我正在构建的许多阵列需要在程序的整个生命周期中持续存在(我添加free()对其余部分的调用!).

xy* points_on_circle(int amount, float radius)
{
  xy* array = malloc(sizeof(xy) * amount);

  float space = (PI * 2) / amount;

  while (amount-- >= 0) {
    float theta = space * amount;

    array[amount].x = sin(theta) * radius;
    array[amount].y = cos(theta) * radius;
  }

  return array;
}
Run Code Online (Sandbox Code Playgroud)

我的突破性xy结构定义如下:

typedef struct { float x; float y; } xy;
Run Code Online (Sandbox Code Playgroud)

我如何调用该函数的示例如下:

xy * outer_points = points_on_circle(360, 5.0);
for(;i<360;i++) {
    //outer_points[i].x
    //outer_points[i].y
}
Run Code Online (Sandbox Code Playgroud)

指针在正确的方向,将不胜感激.

Ste*_*ens 7

在一个功能中分配内存并将其释放到另一个功能中充满了危险.

我将分配内存并将其(内存缓冲区)传递给函数,并带有一个参数,指示允许将多少结构写入缓冲区.

我见过有两个函数的API,一个用于获取所需内存,另一个用于在分配内存后实际获取数据.

[编辑]找到一个例子:http: //msdn.microsoft.com/en-us/library/ms647005%28VS.85%29.aspx


pmg*_*pmg 6

编辑:您正在正确返回数组,但......


考虑一下您正在使用1元素制作数组

xy *outer_points = points_on_circle(1, 5.0);
Run Code Online (Sandbox Code Playgroud)

功能内部会发生什么?
让我们检查 ...

  xy* array = malloc(sizeof(xy) * amount);
Run Code Online (Sandbox Code Playgroud)

1元素分配空间.好!

  while (amount-- >= 0) {
Run Code Online (Sandbox Code Playgroud)

1 在设置返回循环顶部后0,循环执行(并且数量减少)大于或等于
array[0]

  while (amount-- >= 0) {
Run Code Online (Sandbox Code Playgroud)

0大于或等于0循环执行(并且数量减少)
您现在尝试设置array[-1],这是无效的,因为索引引用数组外的区域.


Lun*_*din 6

我会说这个程序设计存在根本缺陷.首先,逻辑上一个正在进行计算的函数与内存分配无关,这是两个不同的东西.其次,除非分配内存的函数和释放内存的函数属于同一个程序模块,否则设计很糟糕,你可能会遇到内存泄漏.相反,将分配留给调用者.

该代码还包含各种危险的做法.避免使用 - 和++运算符作为复杂表达式的一部分,它是导致错误的常见原因.您的代码看起来好像有一个致命的错误并且正在写出数组的界限,只是因为您正在与其他运算符混合.在C语言中没有任何理由这样做,所以不要这样做.

另一个危险的做法是依赖C的隐式类型转换,从int到float(平衡,又称"通常的算术转换").这段代码中的"PI"是什么?它是int,float还是double?代码的结果将根据此情况而有所不同.

这是我建议的(未经测试):

void get_points_on_circle (xy* buffer, size_t items, float radius)
{
  float space = (PI * 2.0f) / items;
  float theta;
  signed int i;

  for(i=items-1; i>=0; i--)
  {
    theta = space * i;

    buffer[i].x = sin(theta) * radius;
    buffer[i].y = cos(theta) * radius;
  }
}
Run Code Online (Sandbox Code Playgroud)