Realloc()

M9
  • Rejestracja:prawie 8 lat
  • Ostatnio:prawie 8 lat
  • Postów:7
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ę :)

Kopiuj
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);
        }
    }
}
edytowany 4x, ostatnio: Patryk27
Patryk27
Nie praktykujemy na tym forum wandalizowania postów.
nalik
  • Rejestracja:ponad 9 lat
  • Ostatnio:20 dni
  • Postów:1039
1

Nie pij jak programujesz ;) Komentarze w kodzie.

Kopiuj
    //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;
    }
Kopiuj
    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);
    }
Kopiuj
    } 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.
        }
    }
edytowany 3x, ostatnio: nalik
M9
  • Rejestracja:prawie 8 lat
  • Ostatnio:prawie 8 lat
  • Postów:7
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 :)

nalik
  • Rejestracja:ponad 9 lat
  • Ostatnio:20 dni
  • Postów:1039
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.

edytowany 4x, ostatnio: nalik
wil
  • Rejestracja:ponad 19 lat
  • Ostatnio:prawie 7 lat
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ę :)

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

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);

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.