Realloc()

0

Witam,
bardzo proszę o pomoc w sprawie 'realloc'. Generalnie jest to implementacja stosu i w momencie kiedy nowy element, który chce zalokować użytkownik, się nie mieści powinniśmy wykorzystać właśnie tą problematyczną funkcję. Jakieś pomysły? Z góry dziękuję :)

void *u_push_stack( u_stack_t *stack, void *item, size_t size ) {
    u_stack_t *newItem;
    if( stack->counter == stack->capacity ) {
        stack->counter = stack->capacity - size;
    } else if ( stack->counter != stack->capacity ) {
        stack->counter = stack->counter - size;
    }
    if ( stack->counter >= 0 ) {
                  //first
        /*newItem->store = item;
        newItem->current = stack -> current;
        stack->current = item;*/
                 //second
        stack->current = stack->current + size;
        memcpy(stack->current, item, size);
                //third
        //*co = ((int*)stack->current - (int*)stack->store)/size;
        //cout << "look " << *co << endl;
    } else {
        void* temp;
        if( (temp = realloc(stack->store, stack->capacity + size)) != NULL ) {
            stack->store = realloc(stack->store, stack->capacity - size);
        }
    }
}
1

Nie pij jak programujesz ;) Komentarze w kodzie.

    //Ale ty widzisz, że to wykona się zawsze, rozumiesz logikę swojego programu, prawda?
    if( stack->counter == stack->capacity ) {
        stack->counter = stack->capacity - size;
    } else if ( stack->counter != stack->capacity ) {
        stack->counter = stack->counter - size;
    }
    if ( stack->counter >= 0 ) {
        // Przypadkiem nie powinieneś odwrócić kolejności tych dwóch instrukcji?
        // Tj. najpierw skopiować dane na stos a dopiero potem przesunać wskaźnik stosu? :)
        stack->current = stack->current + size;
        memcpy(stack->current, item, size);
    }
    } else {
        void* temp;
        // Zastanów się, czy chcesz powiększac stos tylko o rozmiar size. 
        // To oznacza, że każda następna alokacja znowu będzie realokować stos.
        // Przez co zamortyzowany czas wstawiania i usuwania elementów ze stosu nie będzie stały,
        // a liniowy (z racji ciągłej potrzeby realokacji).
        if( (temp = realloc(stack->store, stack->capacity + size)) != NULL ) {
            // Skoro zaalokowałeś stos po raz drugi to przzypisz ten adres (temp) do stack->store
            // Kolejne alokowanie jest bez sensu.
            stack->store = realloc(stack->store, stack->capacity - size);
            // Dodatkowo skoro dokonales ponownej alokacji powinieneś zaktualizować counter, current i capacity.
            // Sugeruję też przesunięcie tej sekcji kodu nad ifa zmieniajac warunek,
            //  a dawnego ifa wykonywać bezwarunowo ponieważ jeszcze musisz wstawić element.
        }
    }
0

Tak, tak wiem, że ponowna alokacja była bez sensu, z tym się jak najbardziej zgadzam. Po drugie kolejność funkcji jest chyba w porządku, główny problem tworzy się wtedy gdy chcę dodać element na stos dla którego muszę zalokować pamięć. Wyskakuje błąd : invalid next size. A i nie piję. To moje pierwsze zetknięcie ze stosami :)

1
milpol94 napisał(a):

Po drugie kolejność funkcji jest chyba w porządku,

Skoro jesteś tego pewien...

główny problem tworzy się wtedy gdy chcę dodać element na stos dla którego muszę zalokować pamięć.

Nie rozumiem. Jak zaalokować pamięc na element? Masz na myśli powiększenie stosu? Z kodu który wkleiłeś taki przypadek użycia nie wynika. Widzę jedynie funkcję, która przepisuje bajty na stos.

Wyskakuje błąd : invalid next size. A i nie piję.

A skąd mamy wiedzieć skąd ten błąd się bierze? Nie wspominasz nic o tym czy to błąd kompilacji, czy pojawiający się podczas działania programu, ani kto go wypisuje i jaki jest warunek wystąpienia tego błędu.

0
milpol94 napisał(a):

Witam,
bardzo proszę o pomoc w sprawie 'realloc'. Generalnie jest to implementacja stosu i w momencie kiedy nowy element, który chce zalokować użytkownik, się nie mieści powinniśmy wykorzystać właśnie tą problematyczną funkcję. Jakieś pomysły? Z góry dziękuję :)

        if( (temp = realloc(stack->store, stack->capacity + size)) != NULL ) {
            stack->store = realloc(stack->store, stack->capacity - size);
        }

Po takim szajsie nie masz już szans na... sukces.

Ten drugi realloc działa na zniszczonym wskaźniku - przez ten pierwszy realloc.

takie coś byłoby tu poprawne:
b = realloc(a, sizb); // a jest już nieaktualne - zostało zniszczone w realloc
c = realloc(b, sizc);

1 użytkowników online, w tym zalogowanych: 0, gości: 1