Skocz do zawartości

Dlaczego Ten Sam Kod W C++ Powoduje Naruszenie Ochrony Pamięci


FC4B

Rekomendowane odpowiedzi

Witam, mam takie pytanie dotyczące programowania w C++. Robię taki dosyć rozbudowany program na Laptopie HP Pavilion z procesorem dwurdzeniowym AMD i program działa bez zarzutu, ale gdy kod źródłowy kompiluje na dwóch stacjonarnych komputerach (jeden to Celeron 1.5 GH z pamięcią 512mb, drugi to AMD Athlon XP 2000+, z pamięcią 768MB) w różnych miejscach wyskakuje mi naruszenie ochrony pamięci. Nawet w takiej przykładowej funkcji, którą mam w pewnym miejscu w jakiejś klasie:

void funkcja()
{
    int *tablica = new int [*liczba];
    memcpy(nowa, stara, (*liczba) * sizeof(int));
    delete [] tablica;
}

i gdy wywołam tą funkcję więcej niż 15 razy wyskakuje błąd. Nie mam pojęcia czym to jest spowodowane, robiłem skan memtest86+ ale wszystko z pamięcią na obu komputerach jest ok, jakie moga byc tego przyczyny?

Odnośnik do komentarza
Udostępnij na innych stronach

i gdy wywołam tą funkcję więcej niż 15 razy wyskakuje błąd. Nie mam pojęcia czym to jest spowodowane, robiłem skan memtest86+ ale wszystko z pamięcią na obu komputerach jest ok, jakie moga byc tego przyczyny?

 

Po 15 uruchomieniach możesz się zaczynać odwoływać do zakresu pamięci który nie jest Ci dany, z z powodów czynników zewnętrznych na laptopie jakimś cudem to działa. Jak możesz to wklej tu cały kod do uruchomienia, lub chociaż całą klasę.

 

Odnośnik do komentarza
Udostępnij na innych stronach

void funkcja()
{
     int *tablica = new int [*liczba];
     memcpy(nowa, stara, (*liczba) * sizeof(int));
     delete [] tablica;
}

 

A co ta funkcja właściwie robi?

Po co allokujesz pamieć tablicy a potem ją usuwasz skoro jej nie używasz ?

Można by skrócić do

 

void funkcja()
{
     memcpy(nowa, stara, (*liczba) * sizeof(int));
}

 

tylko co to "nowa" i "stara" ? Skąd bierzesz te zmienne i czy na pewno prawidłowo rezerwujesz dla nich pamięć ?

Odnośnik do komentarza
Udostępnij na innych stronach

gdy w konstruktorze alokuję nowa pamięć int *tablica = new int [*liczba]; czyli tak jak xdarkflame to przedstawił również po 15 uruchomieniach wyskakuje naruszenie ochrony pamięci, tutaj podaję kawałek kodu:

void klasa_optymalizujaca::optymalizacja2()
{
srand(time(NULL) + getpid());	
wskfunkcjicelu = &funkcja_celu;	 
memcpy(permutacjapodstawowa, permupodst, *liczba * sizeof(int));
for(int i=1; i<=kroki; i++)
{		
	cout << "kroki " << i << ", Funkcja celu = " << *wskfunkcjicelu << flush << "\r";	
	permutacjalosowa pl(liczba, permupodst, a);
	permutacjatymczasowa = pl.permlosowa;		
	funkcjacelu tfc(*liczba, permutacjatymczasowa, tablica_odleglosci);
	tymczasowa_funkcja_celu=&tfc.tymczasowa_funkcja_celu;
	int wskaz = *wskfunkcjicelu;
	metoda1();			 
	if(!K1lub2 && (wskaz>*wskfunkcjicelu))
	{
		memcpy(permupodst, permutacjapodstawowa, (*liczba) * sizeof(int));
	}
}
}
//*********************************
void klasa_optymalizujaca::metoda1()
{
memcpy(permutacja_t, permutacjat, (*liczba) * sizeof(int));
permutacja_t[*liczba] = permutacja_t[0];	
int gamma = 0;

while(!gamma)
{
	(...)
}
if(*wskfunkcjicelu>*tymczasowa_funkcja_celu)
{
	*wskfunkcjicelu = *tymczasowa_funkcja_celu;
	memcpy(permutacjapodstawowa, permutacja_t, (*liczba) * sizeof(int));
}
}
//******************************************************************************

Permutacja oznacza tablicę iluś tam liczb, którą pobieram z pliku, losowa to lekko zmodyfikowana, zas ta klasa sprawdza czy losowa nie jest lepsza od tej pierwotnej.

Odkąd zacząlem pisać programy które wykorzystują pliku tekstowe coraz częściej takie błędy mi się przytrafia... przykładowo ten sam kod programu na innych komputerach (czyli nie laptopie) z plikiem w którym miesci się 52 dane typu:

informacja A
informacja B
1 12 43
2 12 23
3 32 55
4 12 12
EOF

powoduje naruszenie ochrony pamięci w programie przy wspomnianym 15 wywołaniem, ale działa bez bez problemu dla liczby danych 225(?!). Pliki nie różnią się niczym oprócz ilości wierszy, kończą zawsze EOF.

[EDIT]to że z większą ilością danych nie powoduje błędów dopiero zauważyłem pisząc ten komentarz, sprawdze wszystkie pliki, chociaż jest ich około 100. Kiedyś mialem taki problem, że podobnego typu błędy wyskakiwały mi wtedy gdy próbowałem wyświetlić wynik w postaci wykresu stworzonego poprzez opengl.

Odnośnik do komentarza
Udostępnij na innych stronach

Trudno mi tu coś powiedzieć niby wszystko ok wygląda.

 

A jesteś w stanie wygenerować możliwie krótki i logicznie zamknięty kawałek kodu (znaczy taki co się skompiluje) ,

który generuje ten błąd ?

 

A czy na różnych maszynach używasz tego samego pliku binarnego, czy kompilujesz oddzielnie.

Bo może to kwestia ustawień kompilatora ...

 

Widzę , że lubisz *

Odnośnik do komentarza
Udostępnij na innych stronach

Hmmm nie wiem czy to coś pomoże ale zauważyłem, że kiedyś po jednej z aktualizacji SELinux aplikacja, która działała zgłaszała chyba właśnie naruszenie ochrony pamięci a jakiś czas potem po kolejnej aktualizacji SELinux ten problem zniknął...może spróbuj wyłączyć na chwilkę SELinux znaczy przestawić na Permissive by nawet jak coś mu nie pasowało, to żeby mimo wszystko przepuścił aplikację dalej...

Jest to w

System -> Administracja -> SELinux Managment

Tam się przestawia Current Enforcing Mode na Permissive na daną chwilę by zobaczyć właśnie co i jak

Zgaduję, że to wiesz ale gdyby coś zamieściłem informację :)

(Choć jak znam życie są jeszcze min 1-2 sposoby by osiągnąć ten sam efekt :D )

Odnośnik do komentarza
Udostępnij na innych stronach

no właśnie być może coś przez te wskaźniki. Skompilowałem teraz poprzez połączenie ssh i odpalilem to w konsoli ale nadal przez ssh na laptopie, i wszystkie kroki przeszły bez problemu, tylko w dalszej części sprawdzania wyskoczyło naruszenie ochrony pamięci ;/ idę na spacer bo zgłupieć mozna przez te maszyny, im dłużej siedzę tym mniej już to wszystko rozumiem

 

 

 

 

KURDE SUBARU JESTEŚ GENIALNY!!!! on mi nic nie zgłaszał a teraz wyłączyłem i jest wszystko ok!! ja się kilka miesięcy nad tym męczyłem, ale teraz postanowiłem to naprawić i działa!!!!!!!!!!! hehe dzięki masz piwo u mnie

z tymi kilkoma miesiącami to przesadziłem, ale kiedyś miałem podobne błędy i też nie wiedziałem o co chodzi :) jeszcze raz dzięki

 

EDIT nie no za szybko się cieszyłem, przez chwile po wyłączeniu Selinuxa nie wiem czemu było dobrze, a teraz znowu jest tak jak było :) dobra tam zajmę się tym co mam na laptopie i co działa, szkoda nerwów, wtedy przez ssh działało teraz już przez to przestało działac, zwariowac można

EDIT2 znowu kilka testów zrobiłem i jednak wyłączenie Selinuxa działa w 100% :D troszkę chaotyczy jest mój komentarz ale Subaru trafił w dziesiątkę :D

Odnośnik do komentarza
Udostępnij na innych stronach

Link do strony autora:

http://lancet.mit.edu/ga/

 

Używałem tej biblioteki gdy pisałem program do magisterki i powiem Ci, że pozwala ona maksymalnie skupić się na problemie zamiast w nieskończoność debugować metody związane z aspektami "technicznymi" AG. Do tego istnieje ciekawa możliwość generowania statystyk. Co najważniejsze biblioteka ta istnieje zarówno dla linuksa jak i windowsa.

 

There are three things you must do to solve a problem using a genetic algorithm:

 

1. Define a representation

2. Define the genetic operators

3. Define the objective function

 

GAlib helps you with the first two items by providing many examples and pieces from which you can build your representation and operators. In many cases you can use the built-in representations and operators with little or no modification. The objective function is completely up to you. Once you have a representation, operators, and objective measure, you can apply any genetic algorithm to find better solutions to your problem.

Odnośnik do komentarza
Udostępnij na innych stronach

  • 2 weeks later...

Przepraszam, że tak późno, dawno tu nie zaglądałem

Na zakończenie programu

Heh FC4B, najpierw przez 5 sekund czułem radość, że pomogłem potem z 10 sek przy Edit czułem dobicie, a przy Edit2 znowu radość...bawisz się moimi uczuciami nieładnie xD <żart>

 

No a teraz serio

Cieszę się, że mogę od czasu do czasu jednak pomóc :) Jednak 5 lat "wiary w Tux'a" nie poszły na marne :D

 

EDIT

Aha, proszę nie piwo, każdy inny alkohol owszem ale błagam nie piwo :D (ewentualnie coś niealkoholowe ;) )

Odnośnik do komentarza
Udostępnij na innych stronach

Dodam od siebie komentarz, choć przyznam, że nie analizowałem szczegółowego wklejonego kodu.

 

Najczęściej spotykanym przeze mnie problemem z wyrzucaniem "naruszenia ochrony pamięci" w losowych momentach, albo losowych maszynach, jest błąd w samym kodzie źródłowym, a nie w zewnętrznych aplikacjach.

Arbitrażowo oglądnijmy następującą sytuację. Dwa kompy, albo dwa przebiegi na tym samym - A i B. Program prosi o przyznanie dostępu do pamięci (np. malloc), a konkretnie o 99 bajtów, w których omyłkowo, poprzez błąd w programie, próbuje zapisać 101 bajtów.

 

Przychodzi prośba o alokację 99 bajtów, oto co robią A i B.

A przyznaje 99 bajtów, bo to skrupulatny system :P

B przyznaje 128 bajtów, bo chroni bloki pamięci o takim rozmiarze, albo akurat taki jest pod ręką. Oczywiście niewykorzystane tu 29 bajtów może wskazać po jakimś mniejszym mallocu - w końcu i tak ta sama aplikacja, więc nie muszę rozróżniać procesów przy ochronie pamięci.

 

W przypadku A program może się wysypać, zależy to od polityki ochrony pamięci oraz od tego, czy nie trafiamy akurat na blok innego procesu.

W przypadku B program "przejdzie" bezboleśnie.

 

Co do SELinuksa - jak najbardziej zajmuje się sprawami z ochroną pamięci. Potrafi sprawdzać takie rzeczy, jak sposób użycia stosu czy próby uruchomienia programu zapisanego w pamięci. Polecam lekturę google+selinux memory protection.

 

@FC4B

Na forum jest kilku speców od SELinuksa. Jeśli wkleisz raport z /var/log/audit/audit.log, to ktoś z pewnością poradzi co zrobić :P

Odnośnik do komentarza
Udostępnij na innych stronach

Jeśli chcesz dodać odpowiedź, zaloguj się lub zarejestruj nowe konto

Jedynie zarejestrowani użytkownicy mogą komentować zawartość tej strony.

Zarejestruj nowe konto

Załóż nowe konto. To bardzo proste!

Zarejestruj się

Zaloguj się

Posiadasz już konto? Zaloguj się poniżej.

Zaloguj się
×
×
  • Dodaj nową pozycję...