如何在函数中使用局部数组 - ANSI C?
How use local array in function - ANSI C?
我想在传递给函数的数组末尾添加一些内容。
声明一个新的更大的数组或使用 alloc() 哪个更好?
1.
void array_append(int *block, size_t size)
{
int new_block[size + 2];
memcpy(new_block, block, size);
(...append)
}
void array_append(int *block, size_t size)
{
int *new_block = calloc(1, sizeof(int) + 2);
memcpy(new_block, block, size);
(...append)
free(new_block);
}
我不会在任何地方返回新创建的数组。
我只在函数内部使用 new_block。
不修改函数中的原数组。
将 new_block 声明为 static 被省略。
我知道 calloc() / malloc() 是如何工作的,我知道这个操作必须被验证。
new_block 只意味着生活在一个功能中。
我只是想知道哪种解决方案更好,为什么...
问候
您应该动态分配一个数组而不是使用可变长度数组,因为通常在最后一种情况下,代码可能不安全,因为数组的大小相对较大,可能导致堆栈溢出。
I want to add something to the end of the array
但你真的不能。除非用 realloc()
。这就是你的 ...append 技巧可以完成的方式,无论它意味着什么。
如果你需要一个临时数组来处理然后复制到你的数组中(但不是在最后!),那么所有分配方法都是允许的 - 这真的取决于关于频率和尺寸。
如果它经常被调用且大小有限,它可能是一个 static
数组。
增长数组(或一般的内存管理)没有简单的解决方案。在极端情况下,您单独分配每个元素并将它们 link 在一起:一个 linked 列表。
--> 避免到达数组的末尾。定义一个更高的最大值或然后实现一个 linked 列表。
在某些情况下 realloc() 也有意义(大小变化很大,但不经常)。问题是有时必须复制整个数组以保持较大的数组连续:“realloc”,而不是“append”。所以它很“贵”。
I am not returning the newly created array anywhere.
这是问题的一部分。你实际上似乎做了 realloc() 所做的一半:分配新的 space,memcpy() 旧的内容......然后释放旧的和 return 新的数组(-pointer)给来电者。
第一个版本不能return数组指针,因为函数的结尾也是本地自动数组的结尾,无论是否为 VLA。
如果可以追加到现有数组(如果调用者期望这样做并且数组的内存有空间,则可以),您可以仅追加到现有数组。
否则,您需要一个新数组。在这种情况下,数组必须返回给调用者。您可以通过返回指向其第一个元素的指针或让调用者传递一个指向指针的指针来完成此操作,然后修改指向的指针以指向新数组的第一个元素。
当您提供一个新数组时,您必须使用 malloc
或类似的例程为其分配内存。你不应该使用没有 static
的函数内部定义的数组,因为这样的数组的内存只保留到函数执行结束。当您的函数 returns 被调用者调用时,该内存被释放用于其他用途。 (通常,您也不应该使用用 static
声明的数组,但出于良好设计、减少错误以及对函数的多个串行或并行调用的原因。)
我想在传递给函数的数组末尾添加一些内容。
声明一个新的更大的数组或使用 alloc() 哪个更好?
1.
void array_append(int *block, size_t size)
{
int new_block[size + 2];
memcpy(new_block, block, size);
(...append)
}
void array_append(int *block, size_t size)
{
int *new_block = calloc(1, sizeof(int) + 2);
memcpy(new_block, block, size);
(...append)
free(new_block);
}
我不会在任何地方返回新创建的数组。
我只在函数内部使用 new_block。
不修改函数中的原数组。
将 new_block 声明为 static 被省略。
我知道 calloc() / malloc() 是如何工作的,我知道这个操作必须被验证。
new_block 只意味着生活在一个功能中。
我只是想知道哪种解决方案更好,为什么...
问候
您应该动态分配一个数组而不是使用可变长度数组,因为通常在最后一种情况下,代码可能不安全,因为数组的大小相对较大,可能导致堆栈溢出。
I want to add something to the end of the array
但你真的不能。除非用 realloc()
。这就是你的 ...append 技巧可以完成的方式,无论它意味着什么。
如果你需要一个临时数组来处理然后复制到你的数组中(但不是在最后!),那么所有分配方法都是允许的 - 这真的取决于关于频率和尺寸。
如果它经常被调用且大小有限,它可能是一个 static
数组。
增长数组(或一般的内存管理)没有简单的解决方案。在极端情况下,您单独分配每个元素并将它们 link 在一起:一个 linked 列表。
--> 避免到达数组的末尾。定义一个更高的最大值或然后实现一个 linked 列表。
在某些情况下 realloc() 也有意义(大小变化很大,但不经常)。问题是有时必须复制整个数组以保持较大的数组连续:“realloc”,而不是“append”。所以它很“贵”。
I am not returning the newly created array anywhere.
这是问题的一部分。你实际上似乎做了 realloc() 所做的一半:分配新的 space,memcpy() 旧的内容......然后释放旧的和 return 新的数组(-pointer)给来电者。
第一个版本不能return数组指针,因为函数的结尾也是本地自动数组的结尾,无论是否为 VLA。
如果可以追加到现有数组(如果调用者期望这样做并且数组的内存有空间,则可以),您可以仅追加到现有数组。
否则,您需要一个新数组。在这种情况下,数组必须返回给调用者。您可以通过返回指向其第一个元素的指针或让调用者传递一个指向指针的指针来完成此操作,然后修改指向的指针以指向新数组的第一个元素。
当您提供一个新数组时,您必须使用 malloc
或类似的例程为其分配内存。你不应该使用没有 static
的函数内部定义的数组,因为这样的数组的内存只保留到函数执行结束。当您的函数 returns 被调用者调用时,该内存被释放用于其他用途。 (通常,您也不应该使用用 static
声明的数组,但出于良好设计、减少错误以及对函数的多个串行或并行调用的原因。)