[C++] Pointers van een object verwijderen

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

Anoniem: 304397

Topicstarter
Hallo,

Zelf was ik begonnen aan een bibliotheek voor matrix-vermenigvuldiging, en die heeft op het moment een groot geheugenprobleem. Zelf heb ik er een paar dagen mee geworsteld maar ik kom er niet uit en ik hoop dat jullie me kunnen helpen :)

Een matrix-object bestaat uit vier variabelen: int _rows, int _columns, int _size en Type * _values. In de constructor wordt bepaald hoeveel geheugen _values moet reserveren. In mijn oorspronkelijk idee bleef het daarbij maar dat is dus een enorm geheugenlek als het object weer verwijdert wordt. Zelf dacht ik het op te lossen door in de destructor dat geheugen weer vrij te geven. Alleen dat geeft een segfault. Zie de code:

De header:
C++:
1
*snip*


De implementaties van enkele methodes:
C++:
1
*snip*


Het vervelende is dus dat er een segmentatiefout in de destructor optreed met deze code, maar ik dacht dat met deze code _values altijd moest wijzen naar een geldig geheugenadres :S

Heeft iemand hier een idee over? Alvast heel erg bedankt!

[ Voor 82% gewijzigd door RobIII op 04-12-2011 13:04 ]


Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Als je code post, beperk je dan tot relevante (delen van de) code. Die heb je, als het goed is, zo bij de hand want om je probleem te lokaliseren maak je natuurlijk een testcase die bestaat uit de bare essentials om je probleem te kunnen reproduceren. We zitten hier niet om 150+ regels code op afroep voor iedereen te analyseren; debuggen kun je prima zelf (Debuggen: Hoe doe ik dat?).

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

Anoniem: 304397

Topicstarter
Zelf vond ik dat ik al de relevante code eruit had gehaald. Het gaat om het samenspel tussen de constructors en de destructors. Als je meerdere constructors hebt dan lijkt het mij wel relevant om ze allemaal te kunnen zien. Ik wou dat ik het in minder regels kon neerzetten maar dat lukt dus niet omdat het een samenspel is van meerdere methoden. Alle methoden die er niks mee te maken hadden had ik al weg gelaten.

In mijn bericht zei ik ook al dat ik er al een tijd naar gekeken heb. Natuurlijk verwacht ik niet dat dit een plek is waar je mensen op kan afroepen. Ik had wel gehoopt dat mensen me wouden helpen :(

Hoe stel je dan voor dat ik hier mee verder ga? Hoe achterhaal je wanneer een geheugenadres wordt verwijderd op een plek waar je het niet verwacht? Of nog erger, hoe weet je of hij nooit is geset?

Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Je moet toch met een paar regels code je probleem zeker wel kunnen reproduceren? Alle poeha eromheen is toch helemaal niet relevant?

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

Anoniem: 304397

Topicstarter
Blijkbaar ben ik niet in staat om te bepalen wat je wel en niet relevant vind. Zelf vind ik het wel allemaal relevant omdat het allemaal gaat over die pointer, en al die methoden deden iets met die pointer. Als ik wel in staat was om de fout binnen drie regels op te schrijven deed ik dat, vooral omdat ik dan waarschijnlijk ook al een idee had waar het fout gaat.

Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Begin eens met 't verwijderen van code net zo lang tot het probleem zich niet meer voordoet; maak de code zo minimaal mogelijk om 't probleem nog te kunnen (re)produceren. Daarmee maak je 't voor jezelf overzichtelijker (en dus staar je je niet blind op zaken die niet relevant zijn) en voor ons ook makkelijker te overzien wat er nou precies gaande is. Besef wel dat voor jou de code misschien gesneden koek is, maar wij "buitenstaanders" hebben niet de luxe te kunnen "skippen" wat niet relevant is voor 't probleem omdat we de code niet kennen zoals jij die kent. Wij moeten dus alles doorworstelen.
Een dergelijk probleem moet makkelijk binnen < 50 regels code te reproduceren zijn. Alle andere code is overbodige ballast en zorgt er alleen maar voor dat we, en jij idem, door de bomen het bos niet meer zien.

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

Anoniem: 304397

Topicstarter
Zelf ook al geprobeerd, zelf ben ik hier al langer mee bezig.

Ik vind het erg flauw dat je de code weghaalt omdat je het zelf niet relevant vind, laat het dan staan voor mensen die er misschien wel naar willen kijken.

Acties:
  • 0 Henk 'm!

  • naarden 4ever
  • Registratie: Juni 2010
  • Laatst online: 11-07 10:55
Tja... naar welke code moet ik nu kijken?

Goed gedaan hoor, modjes... :F

Daar is Feedback op moderatie binnen de Devschuur voor.

[ Voor 37% gewijzigd door RobIII op 04-12-2011 15:33 ]


Acties:
  • 0 Henk 'm!

  • Ventieldopje
  • Registratie: December 2005
  • Laatst online: 11-07 16:01

Ventieldopje

I'm not your pal, mate!

Ben het wel met de modjes eens, pak gewoon je code en ga het zo ver mogelijk minimaliseren, grote kans dat je je probleem kan reproduceren in een paar regels ;) Dus tja, gewoon je code kopiëren en er zo veel mogelijk uit slopen!

www.maartendeboer.net
1D X | 5Ds | Zeiss Milvus 25, 50, 85 f/1.4 | Zeiss Otus 55 f/1.4 | Canon 200 f/1.8 | Canon 200 f/2 | Canon 300 f/2.8


Acties:
  • 0 Henk 'm!

  • EnderQ
  • Registratie: Januari 2005
  • Laatst online: 11-07 12:50

Acties:
  • 0 Henk 'm!

  • Nactive
  • Registratie: Juni 2011
  • Niet online
Ik wet niet echt wat je wilt doen, maar een simpele matrix klasse ziet er ongeveer zo uit:

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
template <class T>
class Matrix {
public:
    Matrix(int rows_, int cols_) {
        rows = rows_;
        cols = cols_;
        tabel = new T*[rows];
        for (int i = 0; i < rows; i++)
            tabel[i] = new T[cols];
    }

    ~Matrix() {
        for (int i = 0; i < rows; i++)
            delete tabel[i];
        delete tabel;
    }

    T get(int row, int col) {
        return tabel[row][col];
    }

    void set(int row, int col, const T & data) {
        tabel[row][col] = data;
    }

    int rows, cols;
    T  ** tabel;
};


Btw in cpp hebben ze wel de vector in de stl steken. Er is meestal geen reden waarom je die zaken ooit zelf zou maken, behalve als je zeer specifieke eisen hebt kwah performantie ofzo. (http://www.cplusplus.com/reference/stl/vector/)

Voor een matrix van vectors te maken.
C++:
1
vector<vector<double> > matrix;

[ Voor 21% gewijzigd door Nactive op 04-12-2011 14:15 ]


Acties:
  • 0 Henk 'm!

Anoniem: 304397

Topicstarter
Bedankt voor de steun :-)

Helaas is er een mod die me verhindert de code te posten anders kon ik jullie laten zien wat ik wou bouwen. Het gaat om een pointer die in alle mogelijke constructors wordt geset en in de destructor wordt verwijdert. Alleen dit geeft een segfault omdat die pointer (volgens Valgrind) niet altijd geset is. Helaas kan ik maar niet achterhalen hoe dat mogelijk is :S

Klopt, ik weet van het bestaan van de std::vector<>, maar ik had gekozen voor deze implementatie omdat ik dacht dat ik veel van de std::vector<> niet nodig zou hebben.

[ Voor 17% gewijzigd door Anoniem: 304397 op 04-12-2011 14:18 ]


Acties:
  • 0 Henk 'm!

  • Gehakt
  • Registratie: Juli 2002
  • Laatst online: 18:58
Die discussie heb ik ook al eens gehad. Vind het zelf wat overdreven maar goed het is blijkbaar moeilijk om te bepalen of het omeen beginner gaat die de volledige source post of niet.

Hoe zet je de pointer? Is er een kans dat je dubbel aan het deleteen ben?

[ Voor 19% gewijzigd door Gehakt op 04-12-2011 14:33 ]


Acties:
  • 0 Henk 'm!

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Nactive schreef op zondag 04 december 2011 @ 14:10:
Ik wet niet echt wat je wilt doen, maar een simpele matrix klasse ziet er ongeveer zo uit:
Dat is niet exception safe. Als in de loop een allocatie faalt lek je geheugen. Vandaar ook de rede om dit niet te doen en gewoon std::vector te gebruiken.

En als je het al zelf wilt doen, dan encapsuleren met smart pointers. Hoef je ook niks op te ruimen.

[ Voor 12% gewijzigd door Zoijar op 04-12-2011 15:45 ]


Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Anoniem: 304397 schreef op zondag 04 december 2011 @ 14:14:
Helaas is er een mod die me verhindert de code te posten anders kon ik jullie laten zien wat ik wou bouwen. Het gaat om een pointer die in alle mogelijke constructors wordt geset en in de destructor wordt verwijdert.
Zijn dan alle constructors nodig? Alle operator overloads? Alle interne details van wat elke operator doet? Het antwoord is simpel: Neen. Zonder al die boilerplate meuk kun je het probleem ook prima demonstreren. Als jij de moeite niet wil nemen je testcase tot een minimum, overzichtelijk, geheel te verbouwen vind ik het ronduit onbeschoft wel van anderen te verwachten moeite voor jou te doen. Mag je van vinden wat je wil, maar that's how we roll hier in de Devschuur.

Daarbij vind ik het vreemd dat je zoiets niet al uit jezelf doet. Je code tot een minimum beperken (desnoods in een 'nieuw project') om zo uit te sluiten waar 't wel/niet aan ligt is toch gewoon een basisvaardigheid van 't debuggen als je 't mij vraagt.

[ Voor 13% gewijzigd door RobIII op 04-12-2011 15:39 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 27-05 16:00

curry684

left part of the evil twins

Anoniem: 304397 schreef op zondag 04 december 2011 @ 14:14:
Klopt, ik weet van het bestaan van de std::vector<>, maar ik had gekozen voor deze implementatie omdat ik dacht dat ik veel van de std::vector<> niet nodig zou hebben.
En dat is een argument omdat? Code die je niet gebruikt wordt niet gelinkt en kost je dus geen performance of executable size. Het gaat erom of je de mechanieken nodig hebt die het middel je biedt, zo ja, gewoon doen.

Professionele website nodig?


Acties:
  • 0 Henk 'm!

Anoniem: 304397

Topicstarter
RobIII schreef op zondag 04 december 2011 @ 15:36:
[...]

Zijn dan alle constructors nodig? Alle operator overloads? Alle interne details van wat elke operator doet? Het antwoord is simpel: Neen. Zonder al die boilerplate meuk kun je het probleem ook prima demonstreren. Als jij de moeite niet wil nemen je testcase tot een minimum, overzichtelijk, geheel te verbouwen vind ik het ronduit onbeschoft wel van anderen te verwachten moeite voor jou te doen. Mag je van vinden wat je wil, maar that's how we roll hier in de Devschuur.
Dat vind ik een verschrikkelijke attitude: je probeert actief mensen te hinderen die om hulp vragen? En dat vind je sociaal want?

Waarom snap je niet dat ik verschillende pogingen heb gedaan? Sowieso heb ik mijn problemen verteld, zelfs code gedeeld die weer verwijdert is, en je hebt nog niks zinnigs gezegd waarmee ik aan de slag kan. Jij bent een slechte mod als je denk dat dit helpen is.
curry684 schreef op zondag 04 december 2011 @ 23:14:
[...]

En dat is een argument omdat? Code die je niet gebruikt wordt niet gelinkt en kost je dus geen performance of executable size. Het gaat erom of je de mechanieken nodig hebt die het middel je biedt, zo ja, gewoon doen.
Niet helemaal waar, er wordt door gebruik van de std-container nog best veel code bijgetrokken. Echter ik ben het met je eens dat de voordelen opwegen tegen de nadelen.

Tijdens het schrijven was ik in de eerste instantie ervan uitgegaan dat ik alleen een simpele array nodig had. Nu heb ik het herschreven naar vector in de hoop de bug te vinden. En het is gelukt :-)

Het ging fout bij het doorgeven van objecten als referentie. Helaas kan ik de code niet delen.

Acties:
  • 0 Henk 'm!

  • HMS
  • Registratie: Januari 2004
  • Laatst online: 07-07 21:06

HMS

Offtopic?: Je kan altijd nog naar Feedback op moderatie binnen de Devschuur

Daar heb je misschien meer aan.

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 14:59

.oisyn

Moderator Devschuur®

Demotivational Speaker

Anoniem: 304397 schreef op maandag 05 december 2011 @ 00:06:
Niet helemaal waar, er wordt door gebruik van de std-container nog best veel code bijgetrokken.
Bewijs van deze nonsens graag. Zeker voor een vector, die doet precies wat jij ook doet, maar dan gegarandeerd zonder bugs.
Het ging fout bij het doorgeven van objecten als referentie. Helaas kan ik de code niet delen.
Oh kom op - het is hier echt niet zo dat je geen code mag posten. Neem maar eens een kijkje in andere topics. Je weet nu blijkbaar perfect waar het fout ging, dus je bent nu ook in staat de originele functie, de aanroep daarvan, en de verbetering daarvan te posten.

[ Voor 44% gewijzigd door .oisyn op 05-12-2011 02:06 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • NC83
  • Registratie: Juni 2007
  • Laatst online: 08-07 22:30
Anoniem: 304397 schreef op zondag 04 december 2011 @ 13:12:
Zelf vond ik dat ik al de relevante code eruit had gehaald. Het gaat om het samenspel tussen de constructors en de destructors. Als je meerdere constructors hebt dan lijkt het mij wel relevant om ze allemaal te kunnen zien. Ik wou dat ik het in minder regels kon neerzetten maar dat lukt dus niet omdat het een samenspel is van meerdere methoden. Alle methoden die er niks mee te maken hadden had ik al weg gelaten.

In mijn bericht zei ik ook al dat ik er al een tijd naar gekeken heb. Natuurlijk verwacht ik niet dat dit een plek is waar je mensen op kan afroepen. Ik had wel gehoopt dat mensen me wouden helpen :(

Hoe stel je dan voor dat ik hier mee verder ga? Hoe achterhaal je wanneer een geheugenadres wordt verwijderd op een plek waar je het niet verwacht? Of nog erger, hoe weet je of hij nooit is geset?
In het vervolg gebruik je een data breakpoint op het adres wat je alloceert. Iedere keer als dat verandert zal die breakpoint je applicatie stoppen zodat je kunt zien wat er op dat adres gebeurt. Deze link voor MSVC++ en deze voor gcc.
Je hebt nu al een oplossing maar dit kan je in het vervolg ook verder helpen. En hier is een link naar een artikel dat je uitlegt hoe je de MSVS debugger het best gebruikt voor C++.

[ Voor 8% gewijzigd door NC83 op 06-12-2011 00:28 ]

ex-FE Programmer: CMR:DiRT2,DiRT 3, DiRT Showdown, GRID 2, Mad Max

Pagina: 1