Jak sprawdzić czy adrres należy do sterty?

0

Witam,
Mam dany wskaźnik i potrzebuję sprawdzić czy ten wskaźnik wskazuje na adres należący do sterty. Innymi słowy muszę napisać funkcję, która zwróci true jeżeli wskaźnik jest właściwym adresem na stercie i zwróci false w przeciwnym wypadku. Funkcja nie musi być przenośna - docelowy system to Linux ale rozwiązaniami na inne systemy również nie pogardzę :)

0

hym

wydaje mi sie, ze stos jest jednolitym, alignowanym blokiem pamieci.
jesli tak jest, to -

  • odczytac z binarki rozmiar stosu
  • stworzyc zmienna int tab[0]; czy cokowiek - bedzie ona na stosie
  • pobrac jej adres
  • wyzerowac mlodsze boty adresu zgodnie z rozmiarem stosu
  • et voil'a, masz adres bazowy stosu, acz glowe dam ze da sie jakos to prosciej osiagnac :)
  • majac go, porownaj PTR z adresem bazowym stosu. jesli PTR jest poza (po) czubkiem stosu lub dalej niz stacksize (przed) od czubka stosu, to znaczy ze NIE jest na stosie

teraz tylko pozostaje wykluczyc

  • obszary systemowe
  • obszary kodu
  • shmem/mapfile/...

ooo sluchaj, mam genialna w swej prostocie metode
wywolaj na tym delete/free -- jak nie bedzie sigsegv, znaczy sie, sterta ]:>

a tak na serio.. poza przedlubaniem sie przez bebechy malloc/new/free/delete, nie mam pomyslu..

0
quetzalcoatl napisał(a)

ooo sluchaj, mam genialna w swej prostocie metode
wywolaj na tym delete/free -- jak nie bedzie sigsegv, znaczy sie, sterta ]:>

są jeszcze zmienne globalne, które dadzą ten sam efekt.
ja bym zrobił zgodnie z pierwotnym pomysłem, zapamiętał dno stosu, a potem testował czy adres jest w odpowiednim zakresie. Czyli coś w tym stylu:

class isItOnStack
{
   static void* stackBottom; // zapamiętać dno stosu za pomocą jakiegoś obiektu automatycznego

public:
   isItOnStack(int dumy);
   static bool test(void* pinter);
};

void* isItOnStack::stackBottom = 0;
isItOnStack::isItOnStack(int dumy)
{
     stackBottom = &dumy;
}

bool isItOnStack::test(void* pointer)
{
    return pointer<=stackBottom && pointer > &pointer; // w x86 stos adres maleje wraz ze wzrostem stosu, dla innych procesorów może być konieczny jakiś #ifdef SYMBOL
}

static isItOnStack initializer(0);

Nie testowałem, nie jestem pewien czy to zadziała, sam spróbuj.

Swoją drogą mam ważnie, że coś masz źle zaprojektowane. Napisz po co to potrzebujesz to może znajdziemy ci jakieś lepsze rozwiązanie. Np można tak skontrować klasę w ten sposób, by nie dało się jej obiektu stworzyć poza stertą.

0

btw. nie napisalem tego wprost, ale testowanie czy-NIE-jest-na-stosie != czy-jest-na-stercie, a autor pyta o to drugie..

są jeszcze zmienne globalne, które dadzą ten sam efekt

i wiele innych rzeczy tez. z delete/free to byl zart, myslalem ze oczywisty:)

Swoją drogą mam ważnie, że coś masz źle zaprojektowane. Napisz po (..)

tez tak sadze.. bardzo nietypowa rzecz chcesz sprawdzic

0

Przymierzam się do napisania garbage collectora dla c++ i zbieram informację. Chcę użyć algorytmu mark-and-sweep i generalnie w tym algorytmie muszę przejrzeć adresy wszelkich wskaźników, czy przypadkiem nie wskazują na obszar sterty (conservative gc).
Z tego co piszecie to raczej ciężka sprawa, więc pomyślałem, że zrobię sobie swoją "wirtualną" stertę (zaalokowany blok pamięci), w której będę przeprowadzał alokację.

0

Czyli nie powinno być problemu. Masz jakaś klasę bazową, która ma licznik referencji. Przeciążasz operator new dla tej klasy bazowej i w tym operatorze zapamiętujesz listę wskaźników do wszystkich tworzonych obiektów. W operatorze new sprawdzasz czy nie ma problemu z alokowaniem pamięci, jeśli jest, to sprawdzasz w swojej liście czy masz jakieś obiekty do usunięcia (licznik referencji osiągnął limit) i je usuwasz. Nie jest konieczne żadne sprawdzanie, gdzie obiekt został stworzony.

0

Na pewno jest mi potrzebna informacja, jaki obiekt, jakie inne obiekty zaalokował - tak żebym mógł później odtworzyć graf alokacji. Do tego zwykłe przeciążenie new chyba nie wystarczy?

0

Masz racje to nie wystarczy, ale ten problem nie ma nic wspólnego z wiedzą, gdzie dany obiekt istnieje, a tak jak przeciążysz operator new to masz już listę obiektów na stercie. Graf alokacji to już zupełnie inna bardziej skomplikowana bajka.

0

Ok, w takim razie listę zaalokowanych obiektów już mam. I teraz znowu pytanie, czy przypadkiem funkcja, która sprawdzała by czy dany wskaźnik jednak nie była by przydatna. Żeby zbudować taki graf referencji muszę przejść się po zaalokowanej pamięci dla wszystkich obiektów i sprawdzać każdą wartość w pamięci czy przypadkiem nie jest wskaźnikiem na stertę. Mógłbym wziąć najmniejszy i największy adres ze wszystkich obiektów na mojej liście i sprawdzać czy dana wartość mieści się między tym zakresem. Brzmi sensownie, tylko czy na pewno zadziała?

0
rnd napisał(a)

po zaalokowanej pamięci dla wszystkich obiektów i sprawdzać każdą wartość w pamięci czy przypadkiem nie jest wskaźnikiem na stertę

ujmujac trywialnie: zastanawiales sie jak odroznisz przypadkowe dane liczbowe od wlasciwych wskaznikow? a mniej trywialnie: jak zapewnisz zeby kod po automatycznej optymalizacji nadal spelnial zasady ktorych sadzisz ze C++ sie trzyma?:)

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