vector causing memory errors on destruction

Hi everyone.
I am with an annoying error that I cannot manage to fix.
I have a class that have some attributes that are vectors of ints and doubles.
When the class destructor is called it gives the following error:
"Double free or corruption (out)"
But I'ḿ not doing anything complex with the vectors, just attributions, passing as reference and stuff like that.
I chose vectors because so I would not have to worry about memory stuffs. :)

This just occurs sometimes depending on the seed passed to the program, but the operations performed are the same independent of the seed (just the values are different)

Iḿ using Codeblocks on ubuntu 11.10. On windows I didn't have this error.
Any clue of what may be causing it?
I saw something about copy constructors, but I think it's not necessary here, right? as I am just working with simple types and not with objects.
You are not calling the destructor explicitly, are you? The destructor will be called automatically when the vector goes out of scope so you should never explicitly call the destructor.

If that's not it, show some code and it will be easier to help you.
"Hey guys! My code is doing crashing! I switched compilers and didn't have a bug in the last one. I don't think it can be anything I'm doing. What do you guys think?"

I think it's something you're doing. Different compilers generate different code and a bug may manifest itself differently in different environments. You provide pretty much zero context, so any speculation about what may be causing it is purely conjecture.


I am not calling any destructors. But I didn't even implement the class destructor.
My code is very huge, that's why I didn't posted it here. I will post some pieces of it:
this is my class:
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
class grasp{
    public:
        dados d;
        string nomeLOG;
        int round;
        int numClusterHead;
        double min_cost;
        vector<int> ch_index; //variavel que guarda quem é o ch de cada no
        vector<int> ch_list; //variável que guarda quem são os clusters head no round atual
        vector<int> ch_list_lvl_2; //variável que guarda quem são os clusters head no round atual
        vector<double> cost_solution;
        vector<int> ch_routing; //vetor que guarda pra qual nó cada cluster head vai transmitir. Montado no algoritmo de Dijkstra
        vector<double> energia_gasta_round;
        vector< vector<int> > pool_PR;
        vector<double> cost_pool_PR;
        vector<int> dif_pool_PR;

        int PATHRELINK;
        int LVL2CLUSTER;
        int POOL_SIZE;
        double M_CON;
        double M_BL;
        double M_PR;
        int best_sol_it;
        double porcent_local_search;
        int exec;
    public:
        grasp(string instancia, int pr, int lvl2, double param_ls, int index_exec);
        void copy(vector<int> orig, vector<int> &dest);
        double find_min_dist(vector<int> ch_list_aux, vector<int> &ch_index_aux);
        void map_new_ch(int new_ch_coord_X[], int new_ch_coord_Y[], vector<int> &new_ch_list, int elegible[], vector<int> ch_list_it);
        double geraPerturbacao();
        int is_ClusterHead(int node);
        void imprime_ch_list(int round);
        void imprime_iter_results(int iter, double constr, double BL, double PR, double TC, double TLS, double TPR, double TG);
        int valid_ch_list(vector<int> ch_list_param);
        void setup();
        int start();
        double grasp_();
        void sample_greedy(int elegible[], vector<int> &ch_list_it, vector<int> &ch_index_it);
        void random(int elegible[], vector<int> &ch_list_it, vector<int> &ch_index_it);
        double find_cost(vector<int> temp_ch_list, vector<int> temp_ch_index);
        //double find_cost_to_sink(vector<int> temp_ch_list,vector<int> ch_routing);
        int getNumNodes();
        double soma_energia();
        int swap_ch(vector<int> &ch_list_aux, vector<int> &ch_list_index, int elegible[]);
        void coord_perturb(vector<int> ch_list_it, vector<int> &new_ch_list, int elegible[]);
        //double insertClusterHead(vector<int> &ch_list_aux, vector<int> &ch_index_param_aux, int elegible[]);
        double dijkstra(vector<int> ch_list_param, vector<int> &ch_index_param);
        int remove_Cluster_Head(int node, vector<int> &ch_list_aux, vector<int> &ch_index_aux);
        int find_closest_ch(int node,vector<int> &ch_list_aux, vector<int> &ch_index_aux);
        int insert_Cluster_Head(int new_ch, vector<int> &ch_index_param_aux);
        void choose_ch_from_cluster(int dead_ch, vector<int> &ch_list_param, vector<int> &ch_index_param);
        //path relinking
        bool solucao_igual(vector<int> solucao1, vector<int> solucao2);
        double forward_path_relinking(vector<int> &solucao_1, double cost_1, vector<int> &solucao_2, double cost_2);
        double backward_path_relinking(vector<int> &solucao_1, double cost_1, vector<int> &solucao_2, double cost_2);
        int add_sol_to_pool(vector<int> solution, double cost);
        int add_sol_to_pool_dif(vector<int> solution, double cost);
        int solution_in_pool(vector<int> solution);
        void atualiza_difference_pool();
        //second lvl clustering
        void random_2(vector<int> &ch_list_it, vector<int> &ch_index_it, vector<int> new_cluster);
        void sample_greedy_lvl2(vector<int> &ch_list_2, vector<int> &ch_index_2, vector<int> new_cluster, int new_sink);
        void grasp_lvl2(vector<int> new_cluster, int new_sink, vector<int> &ch_list_param, vector<int> &ch_index_param);
        void level2Clustering(vector<int> ch_list_param, vector<int> &ch_index_param, vector<int> &cluster_lvl_2);
        double find_cost_2(vector<int> ch_list_2, vector<int> &ch_index_2, vector<int> new_cluster, int new_sink);

        void gera_logs(int round);
};


I initiate all the variables on the constructor and I don't manipulate anything with pointers or adresses in all the code. I mean, I am not doing anything that may be causing a memory corruption, only using the vector class functions. As I said, with some seeds it happen with others not.
this can be caused by acessing and modifying a index out of the vector range? This is one possibility that the code can be doing. But I think this would give a segmentation fault nor a memory error and at the point of where I access it, not only in the destructor, right?
It is quite possible to cause memory corruption using only the vector class functions.

No stack trace? That's generally the best place to start.
Out of bounds is undefined behaviour.
g++ -D_GLIBCXX_DEBUG main.cpp
that flag will make it throw an exception.
the stack, cire:

1
2
3
4
5
6
7
8
9
10
11
#0 0x7ffff72d23a5	raise() (/lib/x86_64-linux-gnu/libc.so.6:??)
#1 0x7ffff72d5b0b	abort() (/lib/x86_64-linux-gnu/libc.so.6:??)
#2 0x7ffff730a113	??() (/lib/x86_64-linux-gnu/libc.so.6:??)
#3 0x7ffff7314a96	??() (/lib/x86_64-linux-gnu/libc.so.6:??)
#4 0x7ffff7318d7c	free() (/lib/x86_64-linux-gnu/libc.so.6:??)
#5 0x40487a	__gnu_cxx::new_allocator<int>::deallocate(this=0x7fffffffdfa8, __p=0x62a600) (/usr/include/c++/4.6/ext/new_allocator.h:98)
#6 0x4041b6	std::_Vector_base<int, std::allocator<int> >::_M_deallocate(this=0x7fffffffdfa8, __p=0x62a600, __n=8) (/usr/include/c++/4.6/bits/stl_vector.h:156)
#7 0x403bf5	std::_Vector_base<int, std::allocator<int> >::~_Vector_base(this=0x7fffffffdfa8, __in_chrg=<optimized out>) (/usr/include/c++/4.6/bits/stl_vector.h:142)
#8 0x403536	std::vector<int, std::allocator<int> >::~vector(this=0x7fffffffdfa8, __in_chrg=<optimized out>) (/usr/include/c++/4.6/bits/stl_vector.h:351)
#9 0x41a4f3	grasp::~grasp(this=0x7fffffffdec0, __in_chrg=<optimized out>) (grasp.h:12)
#10 0x41a379	main(argc=1, argv=0x7fffffffe1f8) (main.cpp:55) 
my vector of vectors (vector< vector<int> > pool_PR)
receives vector<int> ch_list.
I do a push_back on the pool_PR with ch_list. It's possible that when the destructor of pool_PR is called, it deletes the ch_list and then when the ch_list vector is called it deletes a vector already deleted?

should I make a copy of ch_list and put's the copy on the pool_PR?
I do a push_back on the pool_PR with ch_list. It's possible that when the destructor of pool_PR is called, it deletes the ch_list and then when the ch_list vector is called it deletes a vector already deleted?

No, a copy of ch_list is stored in the vector.
However, all those raw int pointer parameters look like potential trouble, it's easy to mess up somewhere.
Run your program with valgrind to get more clues.
You might consider modifying the destructor for grasp so that the addresses of the various vectors are written somewhere when it's executed.

That in combination with a stack trace should tell you which vector is being molested.
Topic archived. No new replies allowed.