2013-02-20 31 views
5

Jest to teoretyczne pytanie zarówno dla C jak i C++.Czy można zmienić obszar alokacji zmiennych automatycznych w C/C++?

mam typ matrycy 4x4, który jest określony po prostu jako:

typedef float Matrix44[16]; 

również wiele metod, które podejmują Matrix44 jako parametr, na przykład:

bool matrixIsIdentity(Matrix44 m); 

również mieć niestandardowy schemat alokacji pamięci w miejscu, w którym duży obszar pamięci jest wstępnie przydzielony do sterty, a następnie zarządzam przydzieleniami w tej wstępnie zapisanej pamięci ręcznie. Jako takie zastąpiłem/przeciąłem malloc/new z moimi własnymi implementacjami. Problem polega na tym, że zarówno niestandardowe malloc i new, z natury, zwracają wskaźnik, a nie obiekt.

Normalnie, chciałbym po prostu wykonaj następujące czynności:

// Method 1 
1] Matrix44 mat = { ... }; 
2] bool res = matrixIsIdentity(mat); 

Jednak linia 1 przeznaczono mat na stosie, nie w moim niestandardowego obszaru pamięci jako Życzyłbym. Alternatywą jest:

// Method 2 
1] Matrix44 *mmat = myMalloc(...); 
1a] Matrix44 *nmat = new ... 
2] bool res = matrixIsIdentity(*mat); 

Problem polega na tym, że musiałbym zaśmiecić mój kod operatorami dereferencyjnymi. Teraz jedną z opcji byłoby przepisanie wszystkich metod, aby zamiast tego przyjąć Matrix44*, ale, jak to jest teoretyczne, chciałbym założyć, że nie jest to opcja.

Dlatego moje pytanie brzmi: Czy istnieje sposób deklarowania automatycznej zmiennej w C i/lub C++, jak w Method 1 Line 1, ale to śledzić alternatywny system przydziału (jak w Method 2 Line 1)?

(docenić, że może to obejmować dyskusja dotyczy kompilatora, ale nie dodaje się znaczniki w tym celu)

+2

Proszę nie brać tego w niewłaściwy sposób, ale mam nadzieję, że to niemożliwe. Jeśli nie wygląda jak wskaźnik, nie powinien zachowywać się jak wskaźnik. Oczywiście w C++ rzeczy nie zawsze są tak jednoznaczne, heh. – unwind

+0

Myślę, że to przede wszystkim zależy od systemu operacyjnego, którego używasz. Sądzę, że można sobie poradzić z linkerem, aby zmienić układ pamięci. Ale nie jestem pewny ... –

+2

Naprawdę nie powinieneś brać "Matrix44" jako parametru; to jest bardzo drogie. Zadeklaruj takie parametry zamiast "const Matrix44". Czy to może zmniejszyć Twoją chęć przydzielania macierzy na stercie? –

Odpowiedz

4

nie jest możliwe zmienne są automatyczne stos oparte. Ale możesz zrobić, co chcesz w konstruktorze. Więc twój Matrix44 będzie tylko cienkim opakowaniem, powiedzmy Matrix44Impl, który wskaże twoją "niestandardową" pamięć.

+0

W rzeczywistości przydzielono im n automatyczne przechowywanie, które może być dowolne, ale tak, większość czasu to stos. – sharptooth

+0

@ sharptooth, jestem ciekawy, skąd pochodzi * większość czasu *, ponieważ sugeruje, że istnieją przypadki, w których stos nie jest używany. znasz kompilator, który nie używa stosu do realizacji tego? – thang

+1

@thang To zależy od twojej definicji "stosu". Standard C++ w mniejszym lub większym stopniu wymaga alokacji zmiennych automatycznych na stosie * A *, ale nie wszystkie urządzenia mają stos sprzętowy, a wiele osób myli te dwa. –

2

Cóż, to nie jest w 100% dokładnie, o co prosisz, ale stosując odniesienie będzie wyglądać, co chcesz, i zachowują się mniej lub bardziej nie do odróżnienia od tego, co chcesz, jeśli dobrze rozumiem:

Matrix44& mmat = *new Matrix44(...); // or *myMalloc() or whatever 

mmat.Rotate(45.0); 
bool res = matrixIsIdentity(mat); 
... 
delete &mmat; // or myFree(&mmat) or something similar 

Zwróć uwagę na dereferencję na new i adres operatora na delete, co jest wprawdzie trochę dziwne, ale nie widzę powodu, dla którego byłoby błędne składniowo/semantycznie. Kompilator również to akceptuje, i to "działa".

Zdecydowanie odradzam robienie czegoś takiego. Nawet jeśli "działa" doskonale, to wprowadza w błąd. Kod powinien wyglądać jak to, co robi i powinien robić to, na co wygląda. Ten kod nie jest.

Coś wygląda żyje na stosie nie powinno być wymagane (lub nawet możliwe!) Mają być przekazane do delete, i zapewne kod, który robi coś dziwnego naprawdę nie „pracy”, nawet jeśli " działa w porządku".