【发布时间】:2013-08-22 21:13:36
【问题描述】:
我在 C 中有一个函数,它动态分配一个缓冲区,该缓冲区被传递给另一个函数来存储它的返回值。类似于以下虚拟示例:
void other_function(float in, float *out, int out_len) {
/* Fills 'out' with 'out_len' values calculated from 'in' */
}
void function(float *data, int data_len, float *out) {
float *buf;
int buf_len = 2 * data_len, i;
buf = malloc(sizeof(float) * buf_len);
for (i = 0; i < data_len; i++, data++, out++) {
other_function(*data, buf, buf_len);
/* Do some other stuff with the contents of buf and write to *out */
}
free buf;
}
function 由多维数组上的迭代器调用(准确地说,它是一个 NumPy gufunc 内核),因此它被调用数百万次,data_len 的值相同。一遍又一遍地创建和销毁缓冲区似乎很浪费。我通常会将缓冲区的分配移动到调用function 的函数,并向它传递一个指针,但我不直接控制它,所以不可能。相反,我正在考虑执行以下操作:
void function(float *data, int data_len, float *out) {
static float *buf = NULL;
static int buf_len = 0;
int i;
if (buf_len != 2 * data_len) {
buf_len = 2 * data_len;
buf = realloc(buf, sizeof(float) * buf_len); /* same as malloc if buf == NULL */
}
for (i = 0; i < data_len; i++, data++, out++) {
other_function(*data, buf, buf_len);
/* Do some other stuff with the contents of buf and write to *out */
}
}
这意味着我永远不会直接释放我分配的内存:它会在后续调用中重用,然后一直停留在那里直到我的程序退出。这似乎不是正确的做法,但也不算太糟糕,因为分配的内存量总是很小。我是不是多虑了?有更好的方法吗?
【问题讨论】:
-
您对动态缓冲区的大小有任何保证吗?
-
C 中没有 raii,也许您使用的编译器具有 raii 扩展,例如 gcc:gcc.gnu.org/onlinedocs/gcc/Variable-Attributes.html
-
@JustinMeiners 是的,它受到非常严格的控制。最多有 65536 个项目,但这种情况很少见,通常是 16 或 32 个项目。
-
我会使用
<而不是!=...否则您可能仍然需要进行许多分配。更好的是,如果可以,请使用 VLA(如果可以的话,请使用 alloca)。 -
我使用的是 MSVC,我认为它是严格的 C89,所以我认为没有 VLA...