Создание int * с помощью malloc, а затем использование realloc при заполнении

В созданной мной функции я пытаюсь динамически выделить массив int для хранения некоторых значений индекса. Сначала я создаю int * с помощью функции malloc, а затем позволяю циклу сохранять в нем значения som и каждый раз увеличивать указатель. Проблема, с которой я сталкиваюсь, начинается, когда я пытаюсь использовать realloc для увеличения выделения памяти. Когда я делаю это, VS говорит мне, что он работает с неопределенным поведением и ломает программу.

Код выглядит так

void showAvailable(CabinHolder *holder, Booking *booking)
{
    system("cls");

    printf("Choose cabin number \n");
    printf("Start week: &d \t End week: %d", booking->rentPeriod[0], booking->rentPeriod[1]);
    printf("------------------------------------------\n");

    int memory = 5;
    int *indexOfCabin = (int *)malloc(sizeof(int)*memory);
    int counter = 1;

    for (int i = 0; i < CABINS; i++)
    {
        if (counter == memory)
        {
            memory *= 2;
            int *expanded = realloc(indexOfCabin, (memory * sizeof(int)));
            indexOfCabin = expanded;
            expanded = NULL;
        }

        if (booking->cabin->typeOfCabin == holder->arrofCabin[i].typeOfCabin)
        {
            printf("%d. \t Cabin with number %d \t cost: %d per week\n", counter, holder->arrofCabin[i].nr, holder->arrofCabin[i].cost);
            counter++;
            indexOfCabin = &i;
            indexOfCabin++;
        }
    }

    free(indexOfCabin);
    system("pause");
}

Когда я отлаживаю VS, я также вижу, что мой указатель indexOfCabin кажется неопределенным внутри оператора if, чего я не понимаю. Что я здесь пропустил?


person anderssinho    schedule 14.02.2018    source источник
comment
взгляните на этот вопрос: stackoverflow.com/q/605845/812912   -  person Ivaylo Strandjev    schedule 14.02.2018
comment
indexOfCabin = &i отбрасывает выделенную вами память и помещает адрес i в указатель.   -  person user3386109    schedule 14.02.2018
comment
@ user3386109 на самом деле realloc позаботится об освобождении старой памяти, если это необходимо: en.cppreference.com/ w/c/memory/realloc   -  person Ivaylo Strandjev    schedule 14.02.2018
comment
@user3386109 user3386109 ах, теперь, когда вы указали на это, это совершенно верно. Как вместо этого сохранить индекс, например. 17 в indexOfCabin?   -  person anderssinho    schedule 14.02.2018
comment
@anderssinho, пожалуйста, прочитайте документацию realloc. Утверждение не соответствует действительности   -  person Ivaylo Strandjev    schedule 14.02.2018
comment
indexOfCabin можно использовать как массив, например. indexOfCabin[counter] = i;. Но counter должен начинаться с 0 и должен увеличиваться после использования. И indexOfCabin не должно увеличиваться.   -  person user3386109    schedule 14.02.2018
comment
@user3386109 user3386109 ах конечно. Я попробую это и вернусь, если возникнут какие-либо проблемы. Спасибо   -  person anderssinho    schedule 14.02.2018
comment
Подсказка (не имеющая прямого отношения к вашему вопросу, но может облегчить вашу жизнь): вам следует передать управление памятью другой функции вместо того, чтобы смешивать управление памятью и программную логику в одной и той же функции.   -  person Jabberwocky    schedule 14.02.2018
comment
@MichaelWalz, это тоже хороший совет. Выделит эту часть в отдельную функцию, чтобы кодеру было легче понять :)   -  person anderssinho    schedule 14.02.2018


Ответы (1)


Хорошо, после некоторой помощи в разделе комментариев я решил проблему с этим отредактированным сегментом кода.

void showAvailable(CabinHolder *holder, Booking *booking)
{
    system("cls");

    printf("Choose cabin number \n");
    printf("Start week: %d \t End week: %d\n", booking->rentPeriod[0], booking->rentPeriod[1]);
    printf("------------------------------------------\n");

    int memory = 5;
    int *indexOfCabin = malloc(sizeof(int)*memory);
    int counter = 1;
    int items = 0;
    int choice = 0;

    for (int i = 0; i < CABINS; i++)
    {
        if (counter-1 == memory)
        {
            memory *= 2;
            indexOfCabin = realloc(indexOfCabin, (memory * sizeof(int)));
        }

        if (booking->cabin->typeOfCabin == holder->arrofCabin[i].typeOfCabin)
        {
            printf("%d. \t Cabin with number %d \t cost: %d per week\n", counter, holder->arrofCabin[i].nr, holder->arrofCabin[i].cost);
            counter++;
            indexOfCabin[items++] = i;
        }
    }
    free(indexOfCabin);
    system("pause");
}

Во-первых: проблема заключалась в том, что indexOfCabin = &i отбрасывает выделенную вами память и помещает адрес i в указатель вместо того, что я хотел сделать. Теперь мы сохраняем индекс i в указателе.

Во-вторых: indexOfCabin можно использовать как массив, например. indexOfCabin[счетчик] = i;. Но счетчик должен начинаться с 0 и должен увеличиваться после использования. И indexOfCabin не должен увеличиваться

person anderssinho    schedule 14.02.2018
comment
Вы не должны никогда realloc сам указатель (например, indexOfCabin = realloc(indexOfCabin,..., вы должны использовать временный указатель void *tmp = realloc(indexOfCabin,..., затем проверить if (tmp) для проверки перераспределения перед назначением indexOfCabin=tmp;. В противном случае, если realloc не удается, вы перезаписываете исходный адрес указателя NULL, вызывая утечка памяти. - person David C. Rankin; 14.02.2018
comment
@DavidC.Rankin, это совершенно верно, изменит это в коде. - person anderssinho; 14.02.2018
comment
Это также означает отсрочку memory *= 2; до тех пор, пока вы не подтвердите realloc успешно, поэтому ваш realloc будет выглядеть как void *tmp = realloc (indexOfCabin, (memory * 2 * sizeof *indexOfCabin)); if (!tmp) {/* handle error */ break; }; indexOfCabin = tmp; memory *= 2; - person David C. Rankin; 14.02.2018
comment
@DavidC.Rankin спасибо за решение! И понять, почему вы предлагаете это. Теперь это реализовано в моем коде. Обновлю этот пост также с изменением - person anderssinho; 14.02.2018