提问人:ecjb 提问时间:2/22/2023 最后编辑:Chrisecjb 更新时间:2/22/2023 访问量:104
如何在运行时在 C 中增加指针或数组(在编译时不知道结束长度)
How to grow a pointer or an array in C at runtime (without knowing the end length at compile time)
问:
我想在运行时增加一个数组(无需使用 macos 预先处理长度)
我有以下问题
- 是否可以使用数组来做到这一点?
- 如果没有,我应该使用指向 int 的指针吗?
我尝试了以下代码(并期望作为输出)但得到012
000
#include <stdlib.h>
#include <stdio.h>
int main()
{
int *arr = NULL;
size_t n = 0;
for (int i = 0; i < 3; ++i) {
arr = realloc(arr, (n + 1) * sizeof *arr);
arr[n++] = i;
printf("%d", *arr);
}
}
答:
3赞
2 revschux - Reinstate Monica
#1
OP大多拥有它。
它只是每次打印第一个元素。
// printf("%d", *arr);
printf("%d", arr[n-1]);
是否可以使用数组来做到这一点?
不。在 C 中,数组一旦被定义就无法改变大小。
但是,指针分配和引用的内存大小可能会更改。
1赞
chqrlie
2/22/2023
#2
重新分配数组的方式很好,尽管效率低下。你没有得到预期输出的原因是你输出了第一个元素 3 次。
如果您提前知道最终长度,建议一次性分配数组,在其他情况下,需要动态重新分配大型数组,建议按照几何级数使用递增的大小重新分配:
下面是一个使用黄金比例的示例:
#include <stdlib.h>
#include <stdio.h>
int main() {
char *arr = NULL;
size_t size = 0;
size_t pos = 0;
int c;
while ((c = getchar()) != EOF) {
if (pos + 1 > size) {
// increase size by a ratio of 1.625
// with an offset to handle the initial case without a test
size_t new_size = size + (size >> 1) + (size >> 3) + 32;
char *new_arr = realloc(arr, sizeof(*arr) * new_size);
if (new_arr == NULL) {
fprintf(stderr, "cannot reallocate array for %zu bytes\n", new_size);
free(arr);
return 1;
}
arr = new_arr;
size = new_size;
}
arr[pos++] = c;
}
if (arr == NULL) {
fprintf(stderr, "empty file\n");
return 1;
}
arr[pos] = '\0';
char *new_arr = realloc(arr, sizeof(*arr) * (pos + 1));
if (new_arr != NULL) {
arr = new_arr;
size = pos + 1;
}
/* more code to handle full buffer */
free(arr);
return 0;
}
评论
0赞
Erdal Küçük
2/22/2023
size + (size >> 1) + (size >> 3)
这太奇特了,我感觉像找到了一枚金币。只是出于好奇,为什么这个数字.只是武断?看起来没有任何后来的影响(忽略事实,如果 )。32
size == 0
0赞
chqrlie
2/22/2023
@ErdalKüçük:正确,只是一个简单的偏移量来处理没有分支的初始情况。+ 32
评论
realloc
printf(" %d",arr[n - 1]);
printf( "%d: %d and n = %d\n", i, arr[i], n );
realloc()
malloc()
free()
:-)
realloc
realloc