在while循环和realloc'期间,将带有scanf的int放入内存分配中;惯性导航与制导

在while循环和realloc'期间,将带有scanf的int放入内存分配中;惯性导航与制导,c,malloc,scanf,realloc,C,Malloc,Scanf,Realloc,我声明一个int指针并给它分配内存。然后,我向其中输入int,直到用户输入Ctrl+d。循环工作正常,除非我尝试输入7或更多,此时它会给我一个类似“realloc():invalid next size”的错误,并给我一个回溯/内存映射。它必须与我的realloc行有关,但我不确定是什么。有谁能启发我吗 int n= 0, *x, i; double mean = 0.0, median = 0.0, stdDev = 0.0; x = malloc(sizeof(int)); for(i

我声明一个int指针并给它分配内存。然后,我向其中输入int,直到用户输入Ctrl+d。循环工作正常,除非我尝试输入7或更多,此时它会给我一个类似“realloc():invalid next size”的错误,并给我一个回溯/内存映射。它必须与我的
realloc
行有关,但我不确定是什么。有谁能启发我吗

int  n= 0, *x, i;
double mean = 0.0, median = 0.0, stdDev = 0.0;

x =  malloc(sizeof(int));
for(i = 0; scanf("%d", &x[i]) != -1; i++) {
        n++;
        x = realloc(x, n+1 * sizeof(int));
        mean = findMean(x, n);
        median = findMedian(x, n);
        stdDev = findStandardDeviation(x, n, mean);
}

n+1*sizeof(int)
(n+1)*sizeof(int)
问题在于操作顺序:
n+1*sizeof(int)
意味着“将sizeof(int)乘以1,然后再加上n”。可以使用括号强制执行顺序:
(n+1)*sizeof(int)

内存分配可能很昂贵!要求一个合理的内存块,然后每隔一段时间增加一倍,比如说,2。在内存分配系统调用中,操作系统可能会给您一个比您要求的更大的块,以便后续的
realloc
调用更便宜,并使用程序已经可用的内存

最好检查
malloc
realloc
调用是否成功。如果分配请求失败,这些函数将返回NULL

另外,在完成分配的内存时,不要忘记释放它,以避免内存泄漏

编写自己的类似于“vector/ArrayList/list”的界面可能是一个有趣的练习,它可以根据大小进行扩展和收缩,并且可能具有
切片(开始索引、结束索引)
删除(索引)
等操作

下面是一个完整的示例:

#include <stdio.h>
#include <stdlib.h>

int main() {
    int nums_len = 0;
    int nums_capacity = 5;
    int *nums = malloc(nums_capacity * sizeof(int));

    while (scanf("%d", &nums[nums_len]) != -1) {
        if (++nums_len >= nums_capacity) {
            printf("increasing capacity from %d to %d\n", 
                   nums_capacity, nums_capacity * 2);

            nums_capacity *= 2;
            nums = realloc(nums, nums_capacity * sizeof(int));

            if (!nums) {
                fprintf(stderr, "%s: %d: realloc failed\n", 
                        __func__, __LINE__);
                exit(1);
            }
        }

        printf("got: %d\n", nums[nums_len-1]);
    }

    printf("Here are all of the %d numbers you gave me:\n", nums_len);

    for (int i = 0; i < nums_len; i++) {
        printf("%d ", nums[i]);
    }

    puts("");
    free(nums);
    return 0;
}

谢谢你。你会如何避免每次都重新分配?只是一个i%5==0或类似的if语句?每次realloc()之后我也会释放()吗?realloc并不总是那么昂贵。首先,每个malloc/realloc都不是系统调用,它们以非常大的块从操作系统请求内存。然后,他们将它们以较小的片段提供给程序,而不进行任何系统调用。而
realloc
通常只是一个大小更新,而不移动内容。如果“重新分配”的内存是最后分配的内存,则尤其如此。@user3242445否——指针只有一个空闲内存。我添加了一个周期性realloc的示例。这有助于澄清吗?@ggorlen是的,有帮助!但现在不管我的输入如何,我只得到了0,哈哈。。哦,亲爱的,我建议您回滚编辑,然后单独发布更新的代码(如果有的话)。否则,答案将无效,未来的访问者将无法从该问题中获得太多信息。更新的代码中的问题是变量命名不好——您同时使用
i
n
来处理数组上的索引和长度逻辑。最好像我一样使用一个更明确的名称,这将消除关于哪个变量意味着什么的混淆。
for(I=0;scanf(“%d”,&x[I])!=-1;I++){…}
是一个无限循环,如果用户输入非数字文本。建议改为(i=0;scanf(“%d”)和&x[i])==1;i++{…}。