Странная ошибка при использовании realloc

c++ realloc

45 просмотра

3 ответа

Я использую приведенный ниже код и получаю вывод как 8 0 4, а не 8 9 4. Не могли бы вы помочь мне разобраться в проблеме с этим кодом?

#include <cstdlib>
#include <iostream>

using namespace std;

int main() { 
    int *p;

    p = (int*)calloc(2, sizeof(int));

    *(p + 0) = 8;
    *(p + 1) = 9;

    p = (int*)realloc(p, 3);

    *(p + 2) = 4;

    for (int i = 0; i < 3; i++)
        cout << p[i] << " ";

    free(p);
    p = NULL;
}
Автор: Tarun Источник Размещён: 08.11.2019 11:24

Ответы (3)


1 плюс

Для reallocфункции нужен размер в байтах, а не в элементах.

Вам нужно сделать

int *temp = realloc(p, 3 * sizeof(*temp));
if (temp == NULL)
{
    // Handle error...
}
p = temp;

Обратите внимание, что я использую временную переменную для результата realloc. Это потому, что в случае reallocнеудачи он вернет NULLи переназначит результат обратно указателю, который вы передадите в качестве первого аргумента, тогда вы потеряете исходный указатель.

Автор: Some programmer dude Размещён: 20.08.2016 02:12

1 плюс

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

p = (int*)realloc(p, 3 * sizeof(int));

Кстати, вы можете использовать тип *pвместо, intчтобы избежать потенциальных несоответствий, если тип pизменится позже:

p = (int*)realloc(p, 3 * sizeof(*p));

Но поскольку приведение необходимо в C ++, несоответствие, по крайней мере, будет заметно. Вы должны также проверить , является ли calloc()и это realloc()удалось. Они не выдают исключение, а возвращают, NULLкогда не хватает памяти.

Обратите внимание, что вы должны решить, будете ли вы программировать на C или C ++. Эти языки имеют общее происхождение, но заметно отличаются друг от друга, и некоторые идиомы, используемые в одном, считаются плохим стилем в другом, поскольку доступны более подходящие и более безопасные конструкции.

Вот исправленная версия вашей программы на C:

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

int main(void) { 
    int *p = calloc(2, sizeof(*p));
    assert(p != NULL);

    *(p + 0) = 8;
    *(p + 1) = 9;

    p = realloc(p, 3 * sizeof(*p));
    assert(p != NULL);

    *(p + 2) = 4;

    for (int i = 0; i < 3; i++) {
        printf("%d ", p[i]);
    }
    putchar('\n');
    free(p);
    return 0;
}

Хотя здесь есть программа C ++ от PaulMcKenzie, которая реализует то же самое, хотя использование указателя pвсе еще осуждается:

#include <vector>
#include <iostream>

using namespace std;

int main() { 
    std::vector<int> pV(2);
    int *p = pV.data();
    *(p + 0) = 8;
    *(p + 1) = 9;
    pV.resize(3);
    p = pV.data();
    *(p + 2) = 4;
    for (int i = 0; i < 3; i++) {
        cout << p[i] << " ";
    }
}

Как видите, std::vector<int>::resize()занимает количество элементов, не нужно вычислять количество байтов.

Использование указателей и особенно арифметики указателей не является хорошей практикой в ​​C ++, гораздо более простая версия:

#include <vector>
#include <iostream>

using namespace std;

int main() { 
    std::vector<int> v(2);
    v[0] = 8;
    v[1] = 9;
    v.resize(3);
    v[2] = 4;
    for (int i = 0; i < 3; i++) {
        cout << v[i] << " ";
    }
}

Вы также можете использовать перечислитель для распечатки.

Автор: chqrlie Размещён: 20.08.2016 04:12

-2 плюса

Хорошо, у меня проблема:

p = (int*)realloc(p, 3);

значение размера, которое я указал 3, должно было быть3 * sizeof(int)

Автор: Tarun Размещён: 20.08.2016 02:12
Вопросы из категории :
32x32