如何在C语言中动态分配一个整数数组

4
下面展示了我的一部分C代码。
int data[10]={1,3,6,8,1,7,9,1,1,1}; 
b=10;
int out[b];
process(data, &b, out);
alpha (out, b);

data 和 out 都是 int 数组。函数 process 接受数组 data,该数组的长度由 b 指定(b=10),然后进行数学运算,然后返回一个数组 out,其长度再次由 b 指定(未知,因此需要动态分配)。然后将数组 out 与函数 alpha 一起发送。目前函数 alpha 总是发送 out[10],因为在代码的第二行中已声明 b 为 10。如何动态分配数组 out,以便它仅包含函数 process 返回的有效数据。


7
使用malloc函数... - barak manos
我是C语言的新手,因此不知道如何使用malloc。 - H.K
在您的 alpha 函数中,您不需要使用 out 的所有元素,因为您只需传递数组 (b) 的维度即可保持在这些值之间:[0 ... b) - David Ranieri
3个回答

7

您需要了解动态分配和静态分配的区别。

有三种选择:

  • 静态分配:

您需要提前知道数组的长度。它必须是一个数字而不是一个变量:

int out[10];

数组是静态的,只在本地范围内使用。如果你执行:

function do_something()
{
   int out[10];
}

在函数外部,您不能使用 out 数组。但是您可以在外部定义 out 并像这样发送它:

function do_something(int* out)
{
   // do things
}
...
{
   int out[10];
   do_something(out);
}
  • 自动分配

当您执行

int b = 100;
int out[b];

如果您不使用-std=c99或-std=c11标志,将无法在gcc上编译(这个数组), 您会得到一个自动变量,如果您不在作用域之外使用它,这非常方便,但可能有点危险。生成的数组在堆栈中生成,并在超出作用域时被销毁(这就是为什么如果您自由地使用它,它可能会让您陷入麻烦的原因)。请参见https://gcc.gnu.org/onlinedocs/gcc-5.1.0/gcc/Variable-Length.html 我们建议您使用:
动态分配
在堆上生成数组,您需要在完成后清理它。缺点是您需要自己清理它。好处是您可以将其传递并在任何地方使用。
int b=100;
int* out = (int*) malloc(b * sizeof(int));
// do things with out
free(out);

非常重要:不要改变指针out的值。如果你这样做了,那么你就不会释放正确数量的内存。一个好的做法是复制指针,并使用复制后的地址进行释放:

   int b=100;
   int* out = (int*) malloc(b * sizeof(int));
   int* out_copy = out;
   // do things with out. don't touch out_copy
   free(out_copy);

5
C99实际上支持变长数组(Variable Length Array,VLA)。当然,你不能在函数内部分配它并将其返回供外部使用,但你的开头声明是错误的。 - barak manos
你说得对。但是,这里存在作用域的问题。我不确定初学者是否应该去解决这些问题...... 不管怎样,我已经添加了澄清。 - mousomer
3
那不是重点。这个陈述本身就是错误的,而“不要使用静态分配”这个建议也没有意义。如果代码无法编译,那么提问者显然不会使用它。事实上,提问者在问题中明确说明了这一点,因此我不明白告诉他们避免他们没有做的事情如何有任何帮助。 - barak manos
多好的类型转换 :) - David Ranieri
无法在旧版本的C上编译。唯一的标准是C11。这意味着,如果使用旧标准进行编译,就已经知道了。因此,是的,OP应该使用int out[b]; - Michi
看一下 Github,检查有多少项目已经符合新标准。提示:远远不够。 - mousomer

1
int *out;
out=(int *) malloc(sizeof(int) * 10);

这将生成一个大小为10的integer类型数组out

0

你需要将out声明为指针而不是数组,并且需要像处理b一样,将指向out的指针传递给函数。

例如:

void f(int **a, int *size)
{
    *a = malloc(23 * sizeof(**a));
    *size = 23;
}


/* ... */
int *p = NULL;
int b = 0;
f(&p, &b);
/* 'p' has been allocated and 'b' has its size. */

我不明白你的意思。你能把同样的例子应用到我的代码中然后回复吗?从我对 C 语言有限的了解中,我知道一旦声明数组,它总是一个指针。 - H.K
1
你忘记调用 free() 函数了。 - Michi
1
@Habib.Khan 数组永远不是指针。在许多情况下,例如当您将其传递给函数时,会隐式地将其转换为指向数组第一个元素的指针。(您的 process(data, &b, out);process(&data[0], &b, &out[0]); 完全相同)我建议您投资一本好书。 - molbdnilo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接