Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Для новичков > realock неизвестность


Автор: Ivankult 24.5.2011, 21:36
Добрый день. Возникла непонятная проблема с выходом за границы массива или чем-то еще. Есть динамический массив, вызываю функцию, передаю его как параметр. В этой функции добавляю пару элементов, возвращаюсь в main-лабуда какая-то. Скрин : http://img847.imageshack.us/img847/6171/61433370.png

Вот код

main
Код

void main()
{
    setlocale(0,"");
    int count = 0;
    bus *arr=(struct bus*)calloc(0,sizeof(struct bus));

    char ask;
    while(true)
    {        
        cout<<"\n";
        cout<<"1. Добавить автобус в парк\n";
        cout<<"2. Выслать автобус на маршрут\n";
        cout<<"3. Вернуть автобус в парк\n";
        cout<<"4. Показать все автобусы на маршрутах\n";
        cout<<"5. Показать все автобусы в парке\n";
        cout<<"6. Выход\n";
        for(int i=0;i<count;i++)
        {
            cout<<"num: "<<arr[i].num<<"\n";
            cout<<"pos: "<<arr[i].pos<<"\n";
            cout<<"driver: "<<arr[i].driver<<"\n";
            cout<<"marsh: "<<arr[i].marsh<<"\n";
        }
        ask=getch();
        switch(ask)
        {
            case '1':
                read(arr,&count);
                break;
            case '2':
                change(arr,&count,1);
                break;
            case '3':
                change(arr,&count,0);
                break;
            case '4':
                show(arr,&count,1);
                break;
            case '5':
                show(arr,&count,0);
                break;
            case '6':
                return;
            default:
                continue;
        }    
    }
}


read
Код

void read(bus *arr, int *count)
{    
    char ask;
    while(true)
    {
        *count=*count+1;
        arr=(struct bus*)realloc(arr,*count*sizeof(struct bus));
        cout<<"Добавление нового автобуса: \n\n";
        cout<<"Номер автобуса: ";
        cin>>arr[*count-1].num;    
        strcpy(arr[*count-1].driver,".........................");
        arr[*count-1].marsh=-1;
        arr[*count-1].pos=0;

        for(int i=0;i<*count;i++)
        {
            cout<<"num: "<<arr[i].num<<"\n";
            cout<<"pos: "<<arr[i].pos<<"\n";
            cout<<"driver: "<<arr[*count-1].driver<<"\n";
            cout<<"marsh: "<<arr[*count-1].marsh<<"\n";
        }

        cout<<"Продолжить? (y/n): ";
        do ask=getch();
        while(ask!='y' && ask!='n' && ask!='Y' && ask!='N');
        if(ask=='n' || ask=='N')
            break;    
        cout<<"\n";
    }

    cout<<"\nнажмите любую клавишу для возврата в меню\n";
    ask=getch();    
}



в чем проблема может быть? никогда с таким не сталкивался

Заранее благодарю

Автор: borisbn 24.5.2011, 21:50
В ф-ции read arr - это "местая" переменная, и запись в неё рез-та realoc'а никак не повлияет на arr, объявленную в main  

Автор: bsa 24.5.2011, 23:12
Ivankult, замени параметр read(): read(bus *&arr, int *count)
Но лучше используй std::vector<bus>

Автор: Ivankult 24.5.2011, 23:16
я передаю arr как параметр, а точнее передаю указатель на аrr. Read меняет массив, находящийся по тому же адресу в памяти, что и arr из main, это один и тот же массив!

на скрине видно, что при 1 записи все работает норм, а вот при большем количестве записей начинаются косяки. Может проблема в размере структуры(он неверно вычисляет количество памяти для одного элемента)? 

Автор: bsa 24.5.2011, 23:24
Цитата(Ivankult @  24.5.2011,  23:16 Найти цитируемый пост)
на скрине видно, что при 1 записи все работает норм, а вот при большем количестве записей начинаются косяки. 
Косяк в том, что кто-то не читал документацию на функцию realloc. А в ней четко написано, что realloc МОЖЕТ вернуть указатель ОТЛИЧНЫЙ от переданного. Чтобы понять почему, представь, что память представляет собой лист в клеточку. Одна клеточка, например, 4096 байт. malloc может тебе выделить только целое количество клеточек. Таким образом, выделив 100 байт, ты займешь область в 4096 байт. Затем ты делаешь realloc и увеличиваешь область до 4000 байт. Так как за выделенную область не вышли, то realloc возвратит исходный указатель. Затем перевыделяем память опять, требуя уже 4100 байт. И тут realloc видит, что клетка, следующая за текущей, уже занята. Поэтому он выделяет новую область памяти в 2 клетки, копирует туда содержимое старой области, освобождает память и возвращает адрес новой области...

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)