{C++} terminal -> segmentation fault (core dumped)

Tylko tematy nie mieszczące się powyżej.
ekonovember

{C++} terminal -> segmentation fault (core dumped)

Post autor: ekonovember »

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
Awatar użytkownika
DNADesigNed
Sędziwy Jeż
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:

Post autor: DNADesigNed »

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.
Pozdrawiam
Piotr "MoroS" Mrożek - http://dnadesign.pl/
ekonovember

Post autor: ekonovember »

masz racje kod to podstawa tutaj dwie potrzebne metody:

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;
}
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.
Awatar użytkownika
DNADesigNed
Sędziwy Jeż
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:

Post autor: DNADesigNed »

Wiesz co? Podejrzewam, ze zmienna, którą chcesz modyfikować jest lekko poza zasięgiem metody powieksz. Spróbuj w ten sposób:

Kod: Zaznacz cały

template<class typ>
bool eko_dyntab<typ>::powieksz(typ *tab, int o_ile)
... i dalej tak, jak bylo
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).
Pozdrawiam
Piotr "MoroS" Mrożek - http://dnadesign.pl/
ekonovember

Post autor: ekonovember »

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 :]
jj ptak
Piegowaty Guziec
Piegowaty Guziec
Posty: 16
Rejestracja: 12 kwie 2007, 11:54
Płeć: Mężczyzna
Wersja Ubuntu: 7.10

Post autor: jj ptak »

zainteresuj sie valgrindem, on ci pokaze co robisz zle.
ekonovember

Post autor: ekonovember »

fakt niesamowite narzędzie - problem rozwiązany tak teraz wygląda okienko terminala:

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
wcześniej:

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)
a problem był taki:

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;
}
po zakomentowaniu smiga...

moja refleksja na ten temat - systemy unixowe przydzielaja mala sterte :P nie zwolnie 4 bajtow to juz sie nic nie zmiesci :P
Awatar użytkownika
DNADesigNed
Sędziwy Jeż
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:

Post autor: DNADesigNed »

I to właśnie udowadnia, że do rozwiązywania problemów najlepiej widzieć cały kod, a nie tylko jego fragment. Błędy mogą być wszędzie.
Pozdrawiam
Piotr "MoroS" Mrożek - http://dnadesign.pl/
ekonovember

Post autor: ekonovember »

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 :]
jj ptak
Piegowaty Guziec
Piegowaty Guziec
Posty: 16
Rejestracja: 12 kwie 2007, 11:54
Płeć: Mężczyzna
Wersja Ubuntu: 7.10

Post autor: jj ptak »

prawda jest taka ze warto czasem przeleciec vangridem i byc pewnym ze nie ma bledow. uczysz sie porzadnie programowac.
Awatar użytkownika
DNADesigNed
Sędziwy Jeż
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:

Post autor: DNADesigNed »

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 :D) 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/
ekonovember

Post autor: ekonovember »

w cpp jest shared_ptr z biblioteki boosta ktory dzieki zliczaniu referencji trzyma obiekt przy zyciu tak glugo dopuki sa na niego referencje jak niema to wywala.

java jak najbardziej ale narazie mnie nie kreci a garbage collector przeraza :D
Awatar użytkownika
DNADesigNed
Sędziwy Jeż
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:

Post autor: DNADesigNed »

Czyli taki odpowiednik Garbage Collector'a w Java'ie? :)
Pozdrawiam
Piotr "MoroS" Mrożek - http://dnadesign.pl/
ekonovember

Post autor: ekonovember »

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)
Awatar użytkownika
DNADesigNed
Sędziwy Jeż
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:

Post autor: DNADesigNed »

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/
ekonovember

Post autor: ekonovember »

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:

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
}
mniej wiecej cos takiego (podobno jeszcze sie da dziedziczyc sam ten mechanizm jak napisalem wyzej)
Awatar użytkownika
DNADesigNed
Sędziwy Jeż
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:

Post autor: DNADesigNed »

No to z tego, co napisałeś wygląda to jak garbage collector dla C++, z tym że wykonuje się od razu, a nie zależnie od humoru. :P
Pozdrawiam
Piotr "MoroS" Mrożek - http://dnadesign.pl/
Awatar użytkownika
said
Piegowaty Guziec
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)

Post autor: said »

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 ?
Awatar użytkownika
el.pescado
Zakręcona Traszka
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:

Odp: {C++} terminal -> segmentation fault (core dumped)

Post autor: el.pescado »

Nie da się.
kruk87
Piegowaty Guziec
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)

Post autor: kruk87 »

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;
	}
ODPOWIEDZ

Wróć do „Inne”

Kto jest online

Użytkownicy przeglądający to forum: Obecnie na forum nie ma żadnego zarejestrowanego użytkownika i 15 gości