{C++} terminal -> segmentation fault (core dumped)
{C++} terminal -> segmentation fault (core dumped)
witam problem jest następujący mam napisany prosty kontener w C++ (klasa szablonowa)
jest to część innej klasy a ta z kolei jest częścią innej (nie o to tutaj chodzi) w każdym razie:
alokuje nowy ciągły obszar pamięci na kontener (po dodaniu nowego elementu)
przepisuje całość do tymczasowego obszaru
zwalniam obszar kontenera (tego glownego) //tu jest problem
alokuje nowy obszar (zwiększony)
przepisuje z tymczasowego do nowego
zwalniam tymczasowy //tu jest problem
no właśnie to jest chyba standardzik i to oczywiscie powinno działać na systemach unixowych bez problemu tak samo jak działa na windzie (sprawdzalem oczywiscie) ALE pomimo tego że kompiluje sie bez warningów (notabene na tym samym kompilatorze bo pod g++ [dev, anjuta]) to proba uruchomienia programu wywala komunikat o bledzie segmentacji, wywala go tylko kiedy używam sławetnego delete (no ale przecież musze zwalniać pamięć żeby nie było wycieków)
dlatego jeśli ktoś może mi wytłumaczyć dla czego to nie śmiga to bede wdzieczny
jest to część innej klasy a ta z kolei jest częścią innej (nie o to tutaj chodzi) w każdym razie:
alokuje nowy ciągły obszar pamięci na kontener (po dodaniu nowego elementu)
przepisuje całość do tymczasowego obszaru
zwalniam obszar kontenera (tego glownego) //tu jest problem
alokuje nowy obszar (zwiększony)
przepisuje z tymczasowego do nowego
zwalniam tymczasowy //tu jest problem
no właśnie to jest chyba standardzik i to oczywiscie powinno działać na systemach unixowych bez problemu tak samo jak działa na windzie (sprawdzalem oczywiscie) ALE pomimo tego że kompiluje sie bez warningów (notabene na tym samym kompilatorze bo pod g++ [dev, anjuta]) to proba uruchomienia programu wywala komunikat o bledzie segmentacji, wywala go tylko kiedy używam sławetnego delete (no ale przecież musze zwalniać pamięć żeby nie było wycieków)
dlatego jeśli ktoś może mi wytłumaczyć dla czego to nie śmiga to bede wdzieczny
- DNADesigNed
- Sędziwy Jeż
- Posty: 84
- Rejestracja: 30 sie 2007, 17:01
- Płeć: Mężczyzna
- Wersja Ubuntu: 12.04
- Środowisko graficzne: LXDE
- Architektura: x86
- Kontakt:
Ciężko rozmawiać o problemie natury developerskiej, skoro nie widać kodu. Jeżeli nie chcesz/nie możesz udostępnić kodu, to zaprojektuj coś podobnego (i uproszczonego), żeby zaprezentować omawiany przypadek.
Poza tym nie rozumiem czegoś. Skoro potrzebujesz sobie przepisać dane z jednego kontenera do drugiego, większego, to nie łatwiej Ci po prostu stworzyć drugi obiekt i przepisać wartości z pierwszego bez żadnych obszarów pośrednich?
Coś w tym stylu:
1. Alokacja obszaru pamięci.
2. Alokacja zwiększonego obszaru pamięci.
3. Przepisanie danych między obszarami.
4. Zwolnienie obszaru z kroku 1.
Poza tym nie rozumiem czegoś. Skoro potrzebujesz sobie przepisać dane z jednego kontenera do drugiego, większego, to nie łatwiej Ci po prostu stworzyć drugi obiekt i przepisać wartości z pierwszego bez żadnych obszarów pośrednich?
Coś w tym stylu:
1. Alokacja obszaru pamięci.
2. Alokacja zwiększonego obszaru pamięci.
3. Przepisanie danych między obszarami.
4. Zwolnienie obszaru z kroku 1.
Pozdrawiam
Piotr "MoroS" Mrożek - http://dnadesign.pl/
Piotr "MoroS" Mrożek - http://dnadesign.pl/
masz racje kod to podstawa tutaj dwie potrzebne metody:
jak widzisz napisane to mam tak jak u Ciebie jakos nie wzrocilem uwagi na te moje punkty z posta wyzej ze niesa identyczne niz w programie, ale jak sam widzisz to nie jest istotne, problem tkwi w samym delete ktory powoduje wywalenie bledu od procka podczas wykonywania programu, oczywiscie jak zakomentuje linijke z delete to smiga bez problemu tylko ze trace bez sensu pamiec a tak oczywiscie byc nie moze.
Kod: Zaznacz cały
template<class typ>
bool eko_dyntab<typ>::powieksz(int o_ile)
{
typ *tmp;
try
{
tmp= new typ[rozmiar + o_ile];
}
catch(...)
{
return false;
}
for(unsigned int i= 0; i < rozmiar; i++)
tmp[i]= tab[i];
delete []tab; //zwalniam stary obszar tu jest problem (tylko na etapie wykonania programu)
tab= tmp;
rozmiar+= o_ile;
return true;
}
template<class typ>
bool eko_dyntab<typ>::dodaj_el(typ co)
{
if(powieksz(1))
try
{
tab[rozmiar - 1]= co;
}
catch(...)
{
return false;
}
return true;
}
- DNADesigNed
- Sędziwy Jeż
- Posty: 84
- Rejestracja: 30 sie 2007, 17:01
- Płeć: Mężczyzna
- Wersja Ubuntu: 12.04
- Środowisko graficzne: LXDE
- Architektura: x86
- Kontakt:
Wiesz co? Podejrzewam, ze zmienna, którą chcesz modyfikować jest lekko poza zasięgiem metody powieksz. Spróbuj w ten sposób:
To by dużo tłumaczyło, bo segmentation fault występuje dopiero, gdy próbujesz zwolnić pamięć na obszarze nie przydzielnym (czyli de facto usunąć coś, czego nie ma).
Kod: Zaznacz cały
template<class typ>
bool eko_dyntab<typ>::powieksz(typ *tab, int o_ile)
... i dalej tak, jak bylo
Pozdrawiam
Piotr "MoroS" Mrożek - http://dnadesign.pl/
Piotr "MoroS" Mrożek - http://dnadesign.pl/
to znaczy może tego nie widać ale nie musze przekazywać wskaznika na tab bo to składowa klasy (bez operatora zasięgu no bo nie potrzeba) ta składowa wygląda tak:
typ *tab;
wiec jak najbardziej moge to potraktowac delete co zreszta potwierdza to ze nia mam zadnego warninga przy kompilacji (i ze ten sam kod smiga pod windowsem) zastanawiem sie natomiast czy to nie jest jakis problem z przydzialem sterty no ale teraz znowu niewiem czy to na poziomie kompilatora czy co mniej prawdopodobne systemu
moze to smieszne ale sprubowalem tez tak:
delete tab; co nie mialo by wiekszego sensu i na widnowsie nie skompilowaloby sie (tzn pod devem) a tutaj jak najbardziej skompiluje sie ale wywala to samo co poprzednio
i oczywiscie nie chodzi tu o to że sie uparlem na swoj kontener zamiast wrzucic tam "vector" (ktory dziala jesli podmienie moj kontener na niego) tylko o to czemu taki blad - śmieszna sprawa :]
typ *tab;
wiec jak najbardziej moge to potraktowac delete co zreszta potwierdza to ze nia mam zadnego warninga przy kompilacji (i ze ten sam kod smiga pod windowsem) zastanawiem sie natomiast czy to nie jest jakis problem z przydzialem sterty no ale teraz znowu niewiem czy to na poziomie kompilatora czy co mniej prawdopodobne systemu
moze to smieszne ale sprubowalem tez tak:
delete tab; co nie mialo by wiekszego sensu i na widnowsie nie skompilowaloby sie (tzn pod devem) a tutaj jak najbardziej skompiluje sie ale wywala to samo co poprzednio
i oczywiscie nie chodzi tu o to że sie uparlem na swoj kontener zamiast wrzucic tam "vector" (ktory dziala jesli podmienie moj kontener na niego) tylko o to czemu taki blad - śmieszna sprawa :]
fakt niesamowite narzędzie - problem rozwiązany tak teraz wygląda okienko terminala:
wcześniej:
a problem był taki:
po zakomentowaniu smiga...
moja refleksja na ten temat - systemy unixowe przydzielaja mala sterte
nie zwolnie 4 bajtow to juz sie nic nie zmiesci 
Kod: Zaznacz cały
==10600== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 17 from 1)
==10600== malloc/free: in use at exit: 0 bytes in 0 blocks.
==10600== malloc/free: 18 allocs, 18 frees, 356 bytes allocated.
==10600== For counts of detected errors, rerun with: -v
==10600== All heap blocks were freed -- no leaks are possible.
root@eko-komp:/home/eko/programowanie/anjuta/container# ./eko_container a b c d e f g
./eko_container
a
b
c
d
e
f
g
Kod: Zaznacz cały
root@eko-komp:/home/eko/programowanie/anjuta/container# ./eko_container a b c d e f g
Segmentation Fault (core dumped)
Kod: Zaznacz cały
template<class typ>
eko_dyntab<typ>::eko_dyntab()
{
//tab= new typ; //tutaj nie bylo zakomentowanej linijki czyli tracilem sizeof(typ) bajtow w konstruktorze
rozmiar= 0;
}
moja refleksja na ten temat - systemy unixowe przydzielaja mala sterte


- DNADesigNed
- Sędziwy Jeż
- Posty: 84
- Rejestracja: 30 sie 2007, 17:01
- Płeć: Mężczyzna
- Wersja Ubuntu: 12.04
- Środowisko graficzne: LXDE
- Architektura: x86
- Kontakt:
no owszem ale to tak naprawde jest nie tle blad co pewna nieelegancja gubienia kilku bajtow... nie powinno miec to wplywu na dzialanie programu przeciez moge sobie zrobic instrukcje iteracyjna od 0 do 10000 gdzie bede robil wsk= new int; bez najmniejszego delete i do konca dzialania programu powinienem miec zaalokowane 10000 * sizeof(int) bajtow bez (uchwytow do nich) i zero bledow...
no coz dzieki za pomoc :]
no coz dzieki za pomoc :]
- DNADesigNed
- Sędziwy Jeż
- Posty: 84
- Rejestracja: 30 sie 2007, 17:01
- Płeć: Mężczyzna
- Wersja Ubuntu: 12.04
- Środowisko graficzne: LXDE
- Architektura: x86
- Kontakt:
Prawda jest taka, że jeżeli nie chcesz się martwić o alokację i zwalnianie pamięci, to przesiądź się na Java'ę. Bajecznie prosty język.
Przewinąłem się przez C/C++, PHP, Pythona i inne pomniejsze (Pascal, Basic, Assembler ale to ciężko mówić o wygodzie
) i ten język jest dla mnie najwygodniejszy. Poza tym wszystko tym klepniesz: aplikacja konsolowa - nie ma problemu, aplikacja z GUI - spoko, aplikacja web'owa - nic prostszego. Generalnie piszesz to, co chcesz. Na początku podchodziłem do niej bardzo sceptycznie, ale po dwóch latach to nawet w PHP piszę na modłę Java'y (czyli czysta obiektowość). Naprawdę polecam. 



Pozdrawiam
Piotr "MoroS" Mrożek - http://dnadesign.pl/
Piotr "MoroS" Mrożek - http://dnadesign.pl/
- DNADesigNed
- Sędziwy Jeż
- Posty: 84
- Rejestracja: 30 sie 2007, 17:01
- Płeć: Mężczyzna
- Wersja Ubuntu: 12.04
- Środowisko graficzne: LXDE
- Architektura: x86
- Kontakt:
nie taka klasa po ktorej mozna dziedziczyc implementacje zliczania referencji do naszej klasy no i przestac sie martwic o delete, garbage collector to z tego co kojaze z wykladow program ktory smiga w osobnym watku po pamieci i wywala to co nie jest potrzebne (a robi to "kiedy chce") ale generalnie chodzi o to zeby nie martwic sie przydzialem i zwalnianiem (chociaz to jest wolne... podobno sa jeszcze szybsze implementacje ale nie wiem za duzo o tym)
- DNADesigNed
- Sędziwy Jeż
- Posty: 84
- Rejestracja: 30 sie 2007, 17:01
- Płeć: Mężczyzna
- Wersja Ubuntu: 12.04
- Środowisko graficzne: LXDE
- Architektura: x86
- Kontakt:
Generalnie rzeczywiście śmiga w osobnym wątku i zwalnia obszary pamięci, do których nie trzymane są referencje. Nie zauważyłem jednak, żeby wolno działał, ale faktycznie działa kiedy chce (nawet jak specjalnie go wywołasz, to nie gwarantuje Ci, że się uruchomi). W każdym razie jest o tyle łatwiej, że nie trzeba się martwić o zarządzanie pamięcią.
Pozdrawiam
Piotr "MoroS" Mrożek - http://dnadesign.pl/
Piotr "MoroS" Mrożek - http://dnadesign.pl/
a to juz wogole nie wiedzialem ze mozna go wywolywac (jak by sie zachwywal deterministycznie to by chyba kazdemu bylo wygodniej)
a co do boosta:
mniej wiecej cos takiego (podobno jeszcze sie da dziedziczyc sam ten mechanizm jak napisalem wyzej)
a co do boosta:
Kod: Zaznacz cały
#include <co tam trzeba>
#include <boost/shared_ptr.hpp>
class info
{
public:
info()
{
std::cout << "konstruktor" << std::endl;
}
~info()
{
std::cout << "destruktor" << std::endl;
}
};
int main()
{
{ //sztucznie zeby pokazac zasieg
boost::shared_ptr<info> x;
{
boost::shared_ptr<info> a (new info);
x= a;
} //a tutaj nie ginie bo jest na nie referencja
} //tutaj ginie x oraz ginie a
}
- DNADesigNed
- Sędziwy Jeż
- Posty: 84
- Rejestracja: 30 sie 2007, 17:01
- Płeć: Mężczyzna
- Wersja Ubuntu: 12.04
- Środowisko graficzne: LXDE
- Architektura: x86
- Kontakt:
- said
- Piegowaty Guziec
- Posty: 3
- Rejestracja: 26 sty 2008, 14:29
- Płeć: Mężczyzna
- Wersja Ubuntu: 10.10
- Środowisko graficzne: GNOME
Odp: {C++} terminal -> segmentation fault (core dumped)
Czy ktoś może wie jak odwołać sie do zmiennej lokalnej innej funkcji z poziomu funkcji main ?
Przychodzi żona po pracy widząc ekran logowania. Po chwili pyta - Co to za ubudubu ?
- el.pescado
- Zakręcona Traszka
- Posty: 734
- Rejestracja: 26 maja 2005, 11:43
- Płeć: Mężczyzna
- Wersja Ubuntu: inny OS
- Środowisko graficzne: GNOME
- Architektura: x86
- Kontakt:
-
- Piegowaty Guziec
- Posty: 2
- Rejestracja: 02 lis 2008, 10:27
- Płeć: Mężczyzna
- Wersja Ubuntu: 8.04
- Środowisko graficzne: GNOME
Odp: {C++} terminal -> segmentation fault (core dumped)
Witam, podłącze się pod ten topic bo mam dokładnie ten sam problem z segmentation fault. czy mógłby mi ktos powiedzieć dokładnie gdzie robie błąd (wiem że jest to funkcja push);
Kod: Zaznacz cały
#include <iostream>
//#define _size 5
#define start_size 5
class stos
{
public:
void init(int* dane);
void push(int* dane, int dana);
int pop(int* dane);
void destroy(int* dane);
void show(int* dane, int szczyt);
private:
int Size;
int *dane;
int szczyt;
};
void stos::init(int *dane)
{
szczyt=0;
// dane =(int*) malloc(sizeof(int) * _size);
dane = new int[start_size];
Size=start_size;
}
void stos::destroy(int *dane)
{
szczyt=0;
delete [] dane;
Size=start_size;
}
void stos::push(int* dane, int dana)
{
if(szczyt == Size)
{
Size+=start_size;
int* tmp;
tmp = new int[Size];
int i;
for(i=0; i<Size-start_size; i++)
{
tmp[i]=dane[i];
}
delete [] dane;
dane = new int[Size];
for(i=0; i<Size; i++)
{
dane[i]=tmp[i];
}
delete [] tmp;
//realloc(dane, sizeof(int) * Size);
}
dane[szczyt]=dana;
}
int stos::pop(int* dane)
{
if(szczyt>0)
{
szczyt-=1;
}
return dane[szczyt+1];
}
void stos::show(int* dane, int szczyt)
{
int i;
for(i=0; i<szczyt; i++)
{
std::cout << dane[i];
}
}
int main()
{
return 0;
}
Kto jest online
Użytkownicy przeglądający to forum: Obecnie na forum nie ma żadnego zarejestrowanego użytkownika i 15 gości