Как перераспределить на основе размера массива?

Скажем, вы выделили достаточно места в памяти для хранения массива размером 20. Программа работает, и теперь мне нужно достаточно памяти для массива размером, скажем, 40. Я пытался сделать это с помощью realloc, но, похоже, это не работает. Мой код следующий (я пытаюсь найти сумму всех четных членов фибоначчи ниже 4 миллионов):

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

int main(int argc, char** argv){
    int i,sum,size;
    int *fibo;

    size = 20; //initial size of array
    fibo = (int *) malloc(size*sizeof(int));
    fibo[0]=1;
    fibo[1]=1;
    i=2;
    sum=0;

    while(fibo[i-1]<4000000){
            fibo[i] = fibo[i-1]+fibo[i-2];
            printf("fibo[%d] = %d\n", i, fibo[i]);
            if(fibo[i]%2 == 0){
                    sum+= fibo[i];
            }
            i++;
            if(i>size){
                    fibo = (int *) realloc(fibo, (size *= 2)*sizeof(int));
            }
    }

    printf("Sum = %d\n", sum);
    return 0;

}

Кто-нибудь знает, почему realloc терпит неудачу, и как я могу это исправить?


person modsoussi    schedule 26.01.2015    source источник
comment
Что заставляет вас полагать, что это realloc терпит неудачу (а не что-то еще)? Какой симптом вы наблюдаете?   -  person psmears    schedule 27.01.2015
comment
Я знаю, что достигну примерно 23 членов Фибоначчи, прежде чем превысю 4 миллиона. Так что, если я выделяю соответственно в начале, программа работает нормально. Когда я использую realloc, он достигает 20 и больше не может добавить целые числа в массив фибо. т.е. программа перестает работать.   -  person modsoussi    schedule 27.01.2015
comment
(NB вы, вероятно, хотите if (i ›= size), а не if (i › size) – в противном случае, когда вы выполняете realloc, вы только что списали конец массива...)   -  person psmears    schedule 27.01.2015
comment
Постарайтесь быть более конкретным, чем не удается добавить в массив больше целых чисел - как вы узнаете? Это крах? Вы получаете сообщение об ошибке? Если так, то, что это? Эти детали важны :)   -  person psmears    schedule 27.01.2015
comment
Это решило это. Огромное спасибо!   -  person modsoussi    schedule 27.01.2015
comment
Программа перестает работать, и Windows сообщает мне, что пытается найти решение ошибки. Но то, что вы только что упомянули, решило проблему! Я предполагаю, что пытался списать конец массива, что вызывало ошибку.   -  person modsoussi    schedule 27.01.2015
comment
@modsoussi это должно быть if (i == size). Больше никогда не должно становиться возможным, или вы уже вызываете неопределенное поведение.   -  person WhozCraig    schedule 27.01.2015
comment
Кроме того, не применяйте результат malloc (и его друзей). Кроме того, вы должны завести привычку проверять, не удалось ли выделить, проанализировать, открыть файлы и соединения и т. д.   -  person Deduplicator    schedule 27.01.2015
comment
@WhozCraig: Каким образом == преуспевает там, где >= терпит неудачу? В этой ситуации они фактически эквивалентны, не так ли?   -  person psmears    schedule 27.01.2015
comment
@WhozCraig должен быть if (i == size), это интересная мысль. Вы знаете, где это обсуждалось? Не хочу начинать священную войну здесь, но хотел бы здесь за/против этого.   -  person chux - Reinstate Monica    schedule 27.01.2015
comment
@modsoussi Кто или какой текст предложил привести возвращаемое значение malloc()?   -  person chux - Reinstate Monica    schedule 27.01.2015
comment
@chux: код в вопросе возвращает возвращаемое значение как malloc(), так и realloc(); вот и подняли тему.   -  person psmears    schedule 27.01.2015
comment
@chux Не там, где == верно, а >= нет. Моя точка зрения заключалась в том, что инструкция >= будет другой (jne против jl) и не принесет никакой пользы. Учитывая код операции, единственный способ, которым больше, чем может вступить в игру, означает, что предыдущие методы доступа уже вызвали UB, и начинается дождь из кошек. Покрытие всех основ сплошным открытым диапазоном, чего никогда не должно происходить, может не повлиять на рабочий код, но читатель кода вполне может поверить, что i может стать лучше , что, по общему мнению, просто не может произойти и оставаться в сфере определенного поведения.   -  person WhozCraig    schedule 27.01.2015
comment
@psmears Меня интересовало, почему OP изначально выдает malloc() результатов.   -  person chux - Reinstate Monica    schedule 27.01.2015
comment
@chux: Кажется, это очень распространенный анти-шаблон - он повсюду в C, с которым я сталкиваюсь в Интернете...   -  person psmears    schedule 27.01.2015
comment
@psmears Все еще надеюсь узнать от OP, почему OP это сделал - вот почему мой первый комментарий был адресован непосредственно OP. С вашими двумя комментариями сомневаюсь, что теперь на них ответит ОП.   -  person chux - Reinstate Monica    schedule 27.01.2015
comment
@chux Единственная причина, по которой я это сделал, - это то, что я видел это в Интернете, но это было действительно бесполезно.   -  person modsoussi    schedule 27.01.2015


Ответы (1)


На последней итерации i равно 20, но выражение

if(i>size)

ложно, поэтому вы на самом деле не используете realloc, тогда, написав в

fibo[20]

программа обращается к части памяти, которая ей не принадлежит. Изменение выражения на

if(i>=size)

надо исправить :)

person Lamaseed    schedule 26.01.2015