Προς το περιεχόμενο

Προτεινόμενες αναρτήσεις

Δημοσ. (επεξεργασμένο)
51 λεπτά πριν, Dr.Fuzzy είπε

Κάτσε δεν νομίζω οτι έχω καταλάβει. Κάνω το new_quadEdges delete; Που;

Αυτο δεν το γνωριζω εγω. Δεν ξερω πως λειτουργει ο κωδικας. Παντως ενα πραγμα που θα μπορουσες να κανεις είναι αυτό (απλά τα δεδομένα παραμένουν στην μνήμη μέχρι το τέλος του προγράμματος):

delete_quadEdges() {
  for (QuadEdge* qe : new_quadEdges)
    delete qe;
}

main {
  ...
  std::atexit(delete_quadEdges); // Καλό είναι να κοιτάξουμε και το return value.
  ...
}

 

Επεξ/σία από xristos97
  • Like 1
Δημοσ. (επεξεργασμένο)
2 hours ago, xristos97 said:

Αυτο δεν το γνωριζω εγω. Δεν ξερω πως λειτουργει ο κωδικας. 

Εμ αυτή είναι η ερώτηση του 1Μ, που πρεπει να γίνει το deallocation! Το τι καλεί τι φαίνεται λίγο πολύ και στο Valgrind report.

Quote

Παντως ενα πραγμα που θα μπορουσες να κανεις είναι αυτό (απλά τα δεδομένα παραμένουν στην μνήμη μέχρι το τέλος του προγράμματος)

Θα το δοκιμάσω.

Επεξ/σία από Dr.Fuzzy
Δημοσ. (επεξεργασμένο)
On 17/04/2020 at 22:13, Dr.Fuzzy said:

Εμ αυτή είναι η ερώτηση του 1Μ, που πρεπει να γίνει το deallocation! Το τι καλεί τι φαίνεται λίγο πολύ και στο Valgrind report.

Θα το δοκιμάσω.

Χριστός Ανέστη και επανέρχομαι. Δοκίμασα αυτό που πρότεινες και το mem leak μειώθηκε δραματικά αλλά όχι εντελώς (παραμένουν σκουπίδια που δεν καταλαβαίνω γιατί). Επίσης από ένα αριθμό σημείων (συγκεριμενα 14440 σημεία) και πάνω οταν τερματίζει λαμβάνω malloc_consolidate(): invalid chunk size που δε βγάζει ιδιαίτερο νόημα γιατί συμβαίνει.

συγκεκριμένα έχω:

std::vector<Point2d *> new_point2d;

void deletePoints2d() {
    for (Point2d *p2d : new_point2d)
        delete p2d;
}

void Subdivision::InsertSite(const Point2d &x) {
  	...
    Edge *base = MakeEdge();
    Point2d *point2d = new Point2d(x);
    new_point2d.push_back(point2d);
	...
}

std::vector<QuadEdge *> new_quadedges;

void deleteQuadEdges() {
    for (QuadEdge *qe : new_quadedges)
        delete qe;
}

Edge *MakeEdge() {
    QuadEdge *ql = new QuadEdge;
    new_quadedges.push_back(ql);
    return ql->e;
}

και στη main όταν ολοκληρωθεί η InsertSite:

std::atexit(deletePoint2d);
std::atexit(deleteQuadEdges);

και το valgrind report

Quote

delk@Lyapunov:~/Desktop/delaunay$ valgrind -s --tool=memcheck --leak-check=yes ./delaunay -n 80000
==16604== Memcheck, a memory error detector
==16604== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==16604== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==16604== Command: ./delaunay -n 80000
==16604==
==16604== Invalid free() / delete / delete[] / realloc()
==16604==    at 0x4C31478: operator delete(void*) (vg_replace_malloc.c:586)
==16604==    by 0x10DC0D: deleteQuadEdges() (quadedge.cpp:110)
==16604==    by 0x5F06040: __run_exit_handlers (exit.c:108)
==16604==    by 0x5F06139: exit (exit.c:139)
==16604==    by 0x5EE4B9D: (below main) (libc-start.c:344)
==16604==  Address 0x7fd8e30 is 0 bytes inside a block of size 104 free'd
==16604==    at 0x4C31478: operator delete(void*) (vg_replace_malloc.c:586)
==16604==    by 0x10DDB5: DeleteEdge(Edge*) (quadedge.cpp:146)
==16604==    by 0x10E7E8: Subdivision::InsertSite(Point2d const&) (quadedge.cpp:293)
==16604==    by 0x10B612: getArguments(int, char**) (test.cpp:150)
==16604==    by 0x10B0E9: main (test.cpp:61)
==16604==  Block was alloc'd at
==16604==    at 0x4C3045A: operator new(unsigned long) (vg_replace_malloc.c:344)
==16604==    by 0x10DC54: MakeEdge() (quadedge.cpp:114)
==16604==    by 0x10DF7C: Connect(Edge*, Edge*) (quadedge.cpp:180)
==16604==    by 0x10E885: Subdivision::InsertSite(Point2d const&) (quadedge.cpp:306)
==16604==    by 0x10B612: getArguments(int, char**) (test.cpp:150)
==16604==    by 0x10B0E9: main (test.cpp:61)
==16604==
==16604==
==16604== HEAP SUMMARY:
==16604==     in use at exit: 376 bytes in 5 blocks
==16604==   total heap usage: 320,148 allocs, 320,198 frees, 31,972,220 bytes allocated
==16604==
==16604== 344 (32 direct, 312 indirect) bytes in 1 blocks are definitely lost in loss record 5 of 5
==16604==    at 0x4C3045A: operator new(unsigned long) (vg_replace_malloc.c:344)
==16604==    by 0x11028B: __gnu_cxx::new_allocator<QuadEdge*>::allocate(unsigned long, void const*) (new_allocator.h:111)
==16604==    by 0x10FFC9: std::allocator_traits<std::allocator<QuadEdge*> >::allocate(std::allocator<QuadEdge*>&, unsigned long) (alloc_traits.h:436)
==16604==    by 0x10FB5B: std::_Vector_base<QuadEdge*, std::allocator<QuadEdge*> >::_M_allocate(unsigned long) (stl_vector.h:172)
==16604==    by 0x10F3B3: void std::vector<QuadEdge*, std::allocator<QuadEdge*> >::_M_realloc_insert<QuadEdge* const&>(__gnu_cxx::__normal_iterator<QuadEdge**, std::vector<QuadEdge*, std::allocator<QuadEdge*> > >, QuadEdge* const&) (vector.tcc:406)
==16604==    by 0x10F09D: std::vector<QuadEdge*, std::allocator<QuadEdge*> >::push_back(QuadEdge* const&) (stl_vector.h:948)
==16604==    by 0x10DC76: MakeEdge() (quadedge.cpp:115)
==16604==    by 0x10DEB5: Subdivision::Subdivision(Point2d const&, Point2d const&, Point2d const&) (quadedge.cpp:161)
==16604==    by 0x10C854: __static_initialization_and_destruction_0(int, int) (test.cpp:58)
==16604==    by 0x10C887: _GLOBAL__sub_I_program (test.cpp:380)
==16604==    by 0x11084C: __libc_csu_init (in /home/delk/Desktop/delaunay/delaunay)
==16604==    by 0x5EE4B27: (below main) (libc-start.c:266)
==16604==
==16604== LEAK SUMMARY:
==16604==    definitely lost: 32 bytes in 1 blocks
==16604==    indirectly lost: 312 bytes in 3 blocks
==16604==      possibly lost: 0 bytes in 0 blocks
==16604==    still reachable: 32 bytes in 1 blocks
==16604==         suppressed: 0 bytes in 0 blocks
==16604== Reachable blocks (those to which a pointer was found) are not shown.
==16604== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==16604==
==16604== ERROR SUMMARY: 56 errors from 2 contexts (suppressed: 0 from 0)
==16604==
==16604== 55 errors in context 1 of 2:
==16604== Invalid free() / delete / delete[] / realloc()
==16604==    at 0x4C31478: operator delete(void*) (vg_replace_malloc.c:586)
==16604==    by 0x10DC0D: deleteQuadEdges() (quadedge.cpp:110)
==16604==    by 0x5F06040: __run_exit_handlers (exit.c:108)
==16604==    by 0x5F06139: exit (exit.c:139)
==16604==    by 0x5EE4B9D: (below main) (libc-start.c:344)
==16604==  Address 0x7fd8e30 is 0 bytes inside a block of size 104 free'd
==16604==    at 0x4C31478: operator delete(void*) (vg_replace_malloc.c:586)
==16604==    by 0x10DDB5: DeleteEdge(Edge*) (quadedge.cpp:146)
==16604==    by 0x10E7E8: Subdivision::InsertSite(Point2d const&) (quadedge.cpp:293)
==16604==    by 0x10B612: getArguments(int, char**) (test.cpp:150)
==16604==    by 0x10B0E9: main (test.cpp:61)
==16604==  Block was alloc'd at
==16604==    at 0x4C3045A: operator new(unsigned long) (vg_replace_malloc.c:344)
==16604==    by 0x10DC54: MakeEdge() (quadedge.cpp:114)
==16604==    by 0x10DF7C: Connect(Edge*, Edge*) (quadedge.cpp:180)
==16604==    by 0x10E885: Subdivision::InsertSite(Point2d const&) (quadedge.cpp:306)
==16604==    by 0x10B612: getArguments(int, char**) (test.cpp:150)
==16604==    by 0x10B0E9: main (test.cpp:61)
==16604==
==16604== ERROR SUMMARY: 56 errors from 2 contexts (suppressed: 0 from 0)

Μετά απο ψάξιμο το malloc consolidate error προκαλείται απο το συγκεκριμένο deallocation std::atexit(deleteQuadEdges);

Επεξ/σία από Dr.Fuzzy
Δημοσ. (επεξεργασμένο)

Κάνεις διπλά free όπως σου είχα πει: Από αυτά που έχω καταλάβεις δεν έχεις μόνο έναν pointer για κάθε κόμβο με αποτέλεσμα να σβήνεις κάποια δυο φορές.

Spoiler

rust-fernando-borretti-5-638.jpg?cb=1422

Προφανώς δεν είναι τόσο απλά τα πράγματα σε εσένα αλλά αυτή είναι η ιδέα.

Το πρόβλημα εδώ δεν είναι απλά να κάνεις ένα free στο τέλος. Το μόνο που καταφέρνεις είναι να μην σου λέει ότι έχεις memory leak το valgrind.  Πρέπει να καταλάβεις την δομή σου και να γίνονται σωστά delete όταν πλέον ένας κόμβος  "χάνεται". Από την στιγμή που δεν έχεις smart pointers προκύπτουν αυτά τα προβλήματα.😛

Επεξ/σία από kaliakman
Δημοσ.
3 hours ago, kaliakman said:

Κάνεις διπλά free όπως σου είχα πει: Από αυτά που έχω καταλάβεις δεν έχεις μόνο έναν pointer για κάθε κόμβο με αποτέλεσμα να σβήνεις κάποια δυο φορές.

  Hide contents

rust-fernando-borretti-5-638.jpg?cb=1422

Προφανώς δεν είναι τόσο απλά τα πράγματα σε εσένα αλλά αυτή είναι η ιδέα.

Το πρόβλημα εδώ δεν είναι απλά να κάνεις ένα free στο τέλος. Το μόνο που καταφέρνεις είναι να μην σου λέει ότι έχεις memory leak το valgrind.  Πρέπει να καταλάβεις την δομή σου και να γίνονται σωστά delete όταν πλέον ένας κόμβος  "χάνεται". Από την στιγμή που δεν έχεις smart pointers προκύπτουν αυτά τα προβλήματα.😛

Δυστυχώς C++11 δεν υποστηρίζεται οπότε smart pointers γιοκ!

Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε

Πρέπει να είστε μέλος για να αφήσετε σχόλιο

Δημιουργία λογαριασμού

Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!

Δημιουργία νέου λογαριασμού

Σύνδεση

Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.

Συνδεθείτε τώρα
  • Δημιουργία νέου...