Ввод ints с scanf в выделение памяти во время цикла while и перераспределение - PullRequest
1 голос
/ 17 мая 2019

Я объявляю указатель типа int и выделяю для него память. Затем я добавляю в него целые числа, пока пользователь не введет Ctrl + d . Цикл работает нормально, если я не попытаюсь ввести 7 или более, после чего он выдаст мне ошибку, которая выглядит как «realloc (): неверный следующий размер» и выдаст мне карту обратной трассировки / памяти. Это как-то связано с моей 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);
}

Ответы [ 2 ]

2 голосов
/ 17 мая 2019

Проблема в порядке операций: n + 1 * sizeof(int) означает «умножить в 1 раз размер (int), затем добавить n».Вы можете использовать скобки для обеспечения порядка: (n + 1) * sizeof(int).

Выделение памяти может быть дорогим!Попросите разумный кусок памяти, затем увеличивайте его так часто, скажем, в два раза. При системном вызове выделения памяти ОС может дать вам блок большего размера, чем вы просили, чтобы последующие вызовы reallocменее дорогой и использует память, уже доступную вашей программе.

Хорошо проверить, что ваши вызовы malloc и realloc выполнены успешно.Эти функции возвращают NULL, если запрос на выделение завершился неудачей.

Кроме того, не забывайте free выделенную память, когда вы закончите с ней, чтобы избежать утечек памяти.

Это может быть веселоупражнение для написания собственного интерфейса, подобного «vector / ArrayList / list», который расширяется и сжимается до размера и, возможно, содержит такие операции, как slice(start_index, end_index) и remove(index).

. Вот полный пример:

#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;
}

Пример прогона:

5
got: 5
6
got: 6
7
got: 7
8
got: 8
1
increasing capacity from 5 to 10
got: 1
3
got: 3

5
got: 5
6
got: 6
7
got: 7
1
increasing capacity from 10 to 20
got: 1
2
got: 2
3
got: 3
4
got: 4
5
got: 5
6
got: 6
67
got: 67
8
got: 8
1
got: 1
2
got: 2
3
increasing capacity from 20 to 40
got: 3
4
got: 4
1
got: 1
2
got: 2
Here are all of the 23 numbers you gave me:
5 6 7 8 1 3 5 6 7 1 2 3 4 5 6 67 8 1 2 3 4 1 2
1 голос
/ 17 мая 2019

n+1 * sizeof(int) не совпадает с (n+1) * sizeof(int)

...