Alokowanie dużej ilości pamięci. / C++

Bash, C, C++, Java, PHP, Ruby, GTK, Qt i wiele innych - wszystko tutaj.
robal1024
Piegowaty Guziec
Piegowaty Guziec
Posty: 14
Rejestracja: 04 kwie 2008, 16:45
Płeć: Mężczyzna
Wersja Ubuntu: 8.04
Środowisko graficzne: GNOME
Kontakt:

Alokowanie dużej ilości pamięci. / C++

Post autor: robal1024 »

W moim programie potrzebuję zaalokować duży blok pamięci. W kodzie najpierw deklaruję wskaźnik:

Kod: Zaznacz cały

double* great_vector;
A potem następuje instrukcja if, która jeśli się powiedzie następuje alokacja pamięci:

Kod: Zaznacz cały

if(***) {
   great_vector=new double[len];
   ---------------
};
W tym momencie wywołanie

Kod: Zaznacz cały

cout<<great_vector<<endl;
Nie wyrzuca wartości NULL, ani 0. W dalszej części 'ciała' if są pętle, które wypełniają stopniowo zaalokowaną tablicę:

Kod: Zaznacz cały

int w=0;
		for(int i=0; i<n; i++) {
		for(int j=0; j<=i; j++) {
			for(int k=0; k<n; k++) {
				for(int l=0; l<=k; l++) {
					if((0.5*i*(i+1)+j)>=(0.5*k*(k+1)+l)) {
						*(great_vector+w)=calc_2e_direct(basis_form,eff_basis,i,j,k,l,n);
						if(i==j) *(great_vector+w)=*(great_vector+w)/2;
						if(k==l) *(great_vector+w)=*(great_vector+w)/2;
						if((i==k) && (j==l)) *(great_vector+w)=*(great_vector+w)/2;
						w++;
					};
				};
			};
		};
	};
Funkcja calc_2e_direct() liczy wartość double jaka ma się znaleźć w odpowiednim elemencie zaalokowanej pamięci.
Algorytm działa do pewnego momentu, kiedy proces zaczyna zajmować około 50 mb pamięci. Potem następuje segmentation fault.

Proces nie zapełnia całej pamięci ram, zostaje podczas wykonania grubo ponad 2gb. Jak uniknąć tego problemu? Jeśli następuje heap overflow to jak temu zapobiec? Jaki wydajny sposób implementacji zaproponowalibyście dla tego algorytmu.

Dodam, że len*sizeof(double), czyli rozmiar zaalokowanej pamięci ma docelowo być bardzo duży np. 4gb.
Awatar użytkownika
pixelenter
Serdeczny Borsuk
Serdeczny Borsuk
Posty: 194
Rejestracja: 31 gru 2009, 15:41
Płeć: Mężczyzna
Wersja Ubuntu: 10.10
Środowisko graficzne: GNOME
Architektura: x86_64

Odp: Alokowanie dużej ilości pamięci. / C++

Post autor: pixelenter »

Jak się nie mieści w ramie to spróbuj zapisywać do pliku i odczytywać tylko te linijki na których chcesz operować. Polecam ci zrobić klasę.
PS
kody umieszczaj w znacznikach
robal1024
Piegowaty Guziec
Piegowaty Guziec
Posty: 14
Rejestracja: 04 kwie 2008, 16:45
Płeć: Mężczyzna
Wersja Ubuntu: 8.04
Środowisko graficzne: GNOME
Kontakt:

Odp: Alokowanie dużej ilości pamięci. / C++

Post autor: robal1024 »

Problem polega na tym, że mieści się w ramie, podczas działania programu zostaje bardzo dużo ramu. Po prostu w pewnym momencie, arbitralnie, dostaję segmentation fault.
Operowanie plikami na dysku jest znacznie wolniejsze i powoduje spory narzut.
Awatar użytkownika
Struchu
Serdeczny Borsuk
Serdeczny Borsuk
Posty: 116
Rejestracja: 23 mar 2008, 19:58
Płeć: Mężczyzna
Wersja Ubuntu: 11.04
Środowisko graficzne: GNOME
Architektura: x86

Odp: Alokowanie dużej ilości pamięci. / C++

Post autor: Struchu »

A przypadkiem nie wykraczasz poza zaalokowaną pamięć? Bo segfault wskazuje raczej na tę przypadłość niż na przekroczenie dozwolonej pamięci (tutaj raczej powinien się wtrącić system z abortem). Napisz ten kod w jakiejś ludzkiej postaci (znacznik code) to go przeanalizujemy.
Ma zielone, kocie oczy...
Czocher
Piegowaty Guziec
Piegowaty Guziec
Posty: 8
Rejestracja: 09 lut 2006, 22:05
Płeć: Mężczyzna
Wersja Ubuntu: inny OS
Środowisko graficzne: GNOME
Kontakt:

Odp: Alokowanie dużej ilości pamięci. / C++

Post autor: Czocher »

Zainstaluj sobie valgrind i odpal skompilowany z opcją -g program przez:

Kod: Zaznacz cały

valgrind ./a.out
Valgrind to debugger, wskaże ci miejsca gdzie występują błędy i wypisze jakich to typów błędy ;).
robal1024
Piegowaty Guziec
Piegowaty Guziec
Posty: 14
Rejestracja: 04 kwie 2008, 16:45
Płeć: Mężczyzna
Wersja Ubuntu: 8.04
Środowisko graficzne: GNOME
Kontakt:

Odp: Alokowanie dużej ilości pamięci. / C++

Post autor: robal1024 »

Dziękuję wam za odpowiedzi, jeśli valgrind nie pomoże, będę pisał dalej i umieszczę kod w bardziej ludzkiej postaci.
clansman5
Sędziwy Jeż
Sędziwy Jeż
Posty: 77
Rejestracja: 06 sty 2009, 10:59
Płeć: Mężczyzna
Wersja Ubuntu: 9.10
Środowisko graficzne: GNOME
Architektura: x86

Odp: Alokowanie dużej ilości pamięci. / C++

Post autor: clansman5 »

Problem zapewne lezy w sposobie adresowania:

Kod: Zaznacz cały

*(great_vector+w)
elementy great_vector sa typu double, czyli dodanie 1 do great_vector zwieksza go o sizeof(double). Nie wiem dlaczego nie adresujesz w sposob tablicowy ?

Kod: Zaznacz cały

great_vector[w] = blablabla;
luzakwielki
Wytworny Kaczor
Wytworny Kaczor
Posty: 264
Rejestracja: 19 lis 2008, 11:42
Płeć: Mężczyzna
Wersja Ubuntu: inny OS
Środowisko graficzne: KDE Plasma
Architektura: x86_64

Odp: Alokowanie dużej ilości pamięci. / C++

Post autor: luzakwielki »

clansman5 pisze:Problem zapewne lezy w sposobie adresowania:

Kod: Zaznacz cały

*(great_vector+w)
elementy great_vector sa typu double, czyli dodanie 1 do great_vector zwieksza go o sizeof(double). Nie wiem dlaczego nie adresujesz w sposob tablicowy ?

Kod: Zaznacz cały

great_vector[w] = blablabla;
Tu na pewno nie leży problem bo:

Kod: Zaznacz cały

great_vector[w] = blablabla;
kompilator i tak zrozumie:

Kod: Zaznacz cały

*(great_vector+w) = blablabla;
Jest to dokładnie to samo - ba nawet to samo jest jak zrobisz:

Kod: Zaznacz cały

w[great_vector] = blablabla;
bo kompilator sobie z tego zrobi

Kod: Zaznacz cały

*(w+great_vector) = blablabla;
a, że dodawanie jest przemienne będzie działać. Jedyne zastrzeżenia można mieć do tego, żeby tyle dodawać (to samo tyczy się też tab) - lepiej zrobić wskaźnik na great_vector i co pętle robić "++wskaznik;" zaoszczędzi to 7 dodawań * ile razy przebiegnie pętla.

@robal1024: sprawdź czy w jakimś momencie zmienna "w" nie jest większa od "len" (lub czy n^4 nie jest większe od len (no i czy ta liczba mieści się w zwykłym małym int (max 2147483647) bo do takiej zmiennej (w) chcesz wpakować taką liczbę). Co do Valgrind to powinien pomóc, ale jak nie chcesz debuggera pamięci to użyj zwykłego debuggera i sprawdź czy zmienne przy wywaleniu nie mają jakiś dziwnych wartości.
robal1024
Piegowaty Guziec
Piegowaty Guziec
Posty: 14
Rejestracja: 04 kwie 2008, 16:45
Płeć: Mężczyzna
Wersja Ubuntu: 8.04
Środowisko graficzne: GNOME
Kontakt:

Odp: Alokowanie dużej ilości pamięci. / C++

Post autor: robal1024 »

Dziękuję wszystkim za odpowiedź, rozwiązanie jest banalnie proste - wyjechałem poza zakres pamięci jaka została zaalokowana (niewielki błąd przy liczeniu len). Dziękuję, wszystkim za pomoc, dzięki @luzakwielki za sugestię co do przesuwania wskaźnika, w tym wypadku każde zmniejszenie wymagań co do liczby operacji jest cenne.

Problem rozwiązany, do zamknięcia.
ODPOWIEDZ

Wróć do „Programowanie”

Kto jest online

Użytkownicy przeglądający to forum: Amazon [Bot] i 11 gości