IdentifiantMot de passe
Loading...
Mot de passe oubli� ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les r�ponses en temps r�el, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

free() invalid size tr�s bizarre


Sujet :

C++

Vue hybride

Message pr�c�dent Message pr�c�dent   Message suivant Message suivant
  1. #1
    Membre confirm�
    Homme Profil pro
    �tudiant
    Inscrit en
    Mars 2014
    Messages
    126
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activit� : �tudiant

    Informations forums :
    Inscription : Mars 2014
    Messages : 126
    Par d�faut free() invalid size tr�s bizarre
    Bonjour,

    Merci par avance � tous ceux qui essaieront de m'aider, je vous poste le code et je vous dis ce qui se passe !

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    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
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    #ifndef JOHNSON_P
    #define JOHNSON_P
     
    #include "preprocesscl.hpp"
    #include "bellmanfordcl.hpp"
    #include "dijkstracl.hpp"
     
    #include <vector>
    #include <iostream>
     
    /*
        This module provides an implementation of the Johnson's algorithm for computing
        all shortest-paths in a graph that does not contain any negative-weight cycle
    */
     
    template<typename Tvertex, typename Tweight>
    std::vector<Tweight> reweight(std::vector<std::vector<Tweight>>& my_graph);
    /*
        Aim : compute new weights for the graph in order to later apply Dijkstra's algorithm
        Args : the graph
        Return value : none
        Complexity : O(nm)    (reduces to one invocation of Bellman-Ford algorithm)
    */
     
    template<typename Tvertex, typename Tweight>
    std::vector<std::vector<Tweight>> johnson(graph<Tvertex, Tweight>& my_graph);
    /*
        Aim : compute all shortest-paths between all pairs of vertices of the graph
        Args : a graph
        Return value : a 2D vector that contains all shortest-paths
        Complexity : O(nmlog(n))
    */
     
    // OpenCL version, kind of have to specify the parameters for the template
    //void johnson(cl::CommandQueue &cmdQueue, cl::Program &prog, const int n_nodes, cl::Buffer &my_graph, cl::Buffer &distances);
     
    template<typename Tvertex, typename Tweight>
    std::vector<Tweight> reweight(std::vector<std::vector<Tweight>>& my_graph){
     
        std::vector<std::vector<Tweight>> copy_graph = my_graph;           // so that we do not consider all fictitious edges after this function
     
        // we add a fictitious vertex   
     
        std::vector<Tweight> fictitious_edges(std::vector<Tweight>(my_graph.size()));
        copy_graph.push_back(fictitious_edges);
        for(size_t i = 0; i < my_graph.size(); i++)
            copy_graph[i][my_graph.size()] = std::numeric_limits<double>::max() /2 ;
     
        std::vector<Tweight> new_weights = bellman_ford(copy_graph, copy_graph.size()-1); // apply bellman-ford on the graph using the fictitious vertex
                                                                                            // as the source
        for(size_t i = 0; i < my_graph.size(); i++){
            for(size_t j = 0; j < my_graph.size(); j++){
                my_graph[i][j] += new_weights[i] - new_weights[j]; // update the edges
            }
        }
     
        return new_weights;
    }
     
    template<typename Tvertex, typename Tweight>
    std::vector<std::vector<Tweight>> johnson(std::vector<std::vector<Tweight>>& my_graph){
     
        std::vector<std::vector<Tweight>> distances(my_graph.size(), std::vector<Tweight>(my_graph.size(), std::numeric_limits<Tweight>::max()));
     
        std::vector<Tweight> weights = reweight<Tvertex, Tweight>(my_graph);
     
        for(size_t i = 0; i < my_graph.size(); i++){
            std::vector<Tweight> shortest_paths_from_i = dijkstra<Tvertex, Tweight>(my_graph, i);
            for(size_t j = 0; j < my_graph.size(); ++j){
                std::cout << "i : " << i << " j  " << j << std::endl;
                //if(shortest_paths_from_i[j] == std::numeric_limits<Tweight>::max())
                //    distances[i][j] = shortest_paths_from_i[j];
                //else
                //    distances[i][j] = shortest_paths_from_i[j] + weights[j] - weights[i];
            }
        }
     
        return distances;
    }
    /*
    void johnson(cl::CommandQueue &cmdQueue, cl::Program &prog, const int n_nodes, cl::Buffer &my_graph, cl::Buffer &distances){
     
        cl::Kernel kernel(prog, "johnson");
        kernel.setArg(0, (cl_uint) n_nodes);
        kernel.setArg(1, my_graph);
        kernel.setArg(2, distances);
        size_t group_size = 16;
        cl::NDRange local(group_size, group_size);
        cl::NDRange global((n_nodes + group_size - 1) / group_size * group_size,
                           (n_nodes + group_size - 1) / group_size * group_size);
        cmdQueue.enqueueNDRangeKernel(kernel, cl::NullRange, global, local);
     
    }
     */
    #endif
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    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
    #include "preprocesscl.hpp"
    #include "bellmanfordcl.hpp"
    #include "johnsoncl.hpp"
    #include "dijkstracl.hpp"
    #include <chrono>
    //#include <omp.h>
     
     
    //#include "boost/graph/johnson_all_pairs_shortest.hpp"
     
    #include <iostream>
     
    int main(int argc, char* argv[]){
    /*
        std::vector<std::vector<double>> my_graph = parse_graph<long unsigned int, double>(argv[1]);
     
        std::vector<double> distances = bellman_ford<long unsigned int, double>(my_graph, 0);
     
        std::vector<double> new_w = reweight<long unsigned int, double>(my_graph);
     
        for(size_t k = 0 ; k < new_w.size(); k++)
            std::cout << new_w[k] << " " ;
        std::cout << std::endl << std::endl;
     
        std::vector<double> distances_d = dijkstra(my_graph, 0);
     
        for(size_t i = 0; i < distances_d.size(); i++){
            std::cout << distances_d[i] << " " ;
        }
     
        std::cout << std::endl;
    */
     
        std::vector<std::vector<double>> my_graph = parse_graph<long unsigned int, double>(argv[1]);
     
        std::chrono::high_resolution_clock::time_point t1 = std::chrono::high_resolution_clock::now();
     
        std::vector<std::vector<double>> distances = johnson<long unsigned int, double>(my_graph);
     
        std::chrono::high_resolution_clock::time_point t2 = std::chrono::high_resolution_clock::now();
     
        std::chrono::duration<double> time_span = std::chrono::duration_cast<std::chrono::duration<double>>(t2 - t1);
     
        std::cout << time_span.count();
        std::cout << std::endl;
     
     
        return 0;
     
    }
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    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
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    #ifndef DIJKSTRA_P
    #define DIJKSTRA_P
     
    #include <iostream>
    #include <vector>
    #include "heap_generic.hpp"
    #include "preprocesscl.hpp"
    #include <limits>
    #include <omp.h>
     
    /*
     
    std::chrono::high_resolution_clock::time_point t1 = std::chrono::high_resolution_clock::now();
     
    std::chrono::high_resolution_clock::time_point t2 = std::chrono::high_resolution_clock::now();
            std::chrono::duration<double> time_span = std::chrono::duration_cast<std::chrono::duration<double>>(t2 - t1);
     
            std::cout << time_span.count();
            std::cout << std::endl;
    */
    template<typename Tnode, typename Tweight>
    struct dijkstra_pair {
        Tnode pivot;
        Tweight key;
     
        bool operator<(dijkstra_pair &other_pair){
            return key < other_pair.key;
        }
     
        bool operator>(dijkstra_pair &other_pair){
            return key > other_pair.key; 
        }
    };
     
    template<typename Tnode, typename Tweight>
    std::ostream& operator<<(std::ostream& out, const dijkstra_pair<Tnode, Tweight>& pair){
        out << "Vertex : " << pair.pivot << ", key : " << pair.key << std::endl;
        return out;
    }
     
    template<typename Tnode, typename Tweight>
    std::vector<Tweight> dijkstra(const std::vector<std::vector<Tweight>>& my_graph, const Tnode node);
    /*
        Aim : compute the shortest distances from source to every other vertex
        Args : the graph, represented as defined in preprocess.hpp and a source vertex
        Return value : a 1D array that contains the shortest distances
        Complexity : O(mlog(n))
    */
     
    template<typename Tnode, typename Tweight>
    std::vector<Tweight> initialize_distances(const std::vector<std::vector<Tweight>>& my_graph, const Tnode source);
    /*
        Aim : initialize the shortest paths, a shortest path is equal to the value of the edge between source and vertex if it exists, 0 between source
              and source, infinity represented as numeric_limits<Tweight>::max() otherwise
        Args : a graph and a source node
        Return value : a 1D array containing all initialized distances
        Complexity : O(n)
    */
     
    template<typename Tnode, typename Tweight>
    std::vector<Tweight> dijkstra(const std::vector<std::vector<Tweight>>& my_graph, const Tnode source){
     
        //to store our computed distances
        std::vector<Tweight> distances = initialize_distances(my_graph, source);
     
     
        std::vector<bool> in_heap(my_graph.size(), false);                  // to keep track of nodes in the heap
        std::vector<bool> processed(my_graph.size(), false);                // to keep track of processed nodes
     
        std::vector<dijkstra_pair<Tnode, Tweight>> heap = create_heap<dijkstra_pair<Tnode, Tweight>>();        // our amazing heap for BLAZINGLY FAST
                                                                                                               // implementation
     
        insert(heap, {source, 0});             // insert the source and mark it as "in the heap"
        in_heap[source] = true;
     
        while(size_heap(heap) != 1){
     
            dijkstra_pair<Tnode, Tweight> new_pair = pop(heap);
            in_heap[new_pair.pivot] = false;                             // old min is not in the heap anymore
            processed[new_pair.pivot] = true;                            // old min is now processed           
            distances[new_pair.pivot] = new_pair.key;                    // the old key is the permanent distance between source and associated node
     
            for(size_t i = 0; i < my_graph.size(); i++){          // we check all outgoing edges of the new added vertex
     
                edge<Tnode, Tweight> current_edge{new_pair.pivot, i, my_graph[new_pair.pivot][i]};
                Tnode current_node = current_edge.head_;                                 // the head of an outgoing edge whose tail is the new added vertex
     
                 // if already in the heap we update its key
                if(in_heap[current_node]){                                              
     
                    Tweight old_key = delete_element(heap, current_node).key;
                    Tweight new_key = std::min(old_key, distances[new_pair.pivot] + current_edge.weight_);
                    insert(heap, {current_node, new_key});
                }
     
                else if(!processed[current_node]){   
     
                    // otherwise we compute its key and insert it
                    //Tweight new_key = compute_key(my_graph, current_node, in_heap, distances);
                    Tweight new_key = distances[new_pair.pivot] + current_edge.weight_;
                    insert(heap, {current_node, new_key});
     
                    in_heap[current_node] = true;
                }
            }
        }
     
        return distances;
    }
     
    template<typename Tnode, typename Tweight>
    std::vector<Tweight> initialize_distances(const std::vector<std::vector<Tweight>>& my_graph, const Tnode source){
        std::vector<Tweight> distances(my_graph.size(), std::numeric_limits<Tweight>::max()/2);                  // std::numeric_limits<int> causes dist[smth] 
                                                                                        // + stuff to be -X which is always less than current key
        distances[source] = 0;
        for(size_t i = 0; i < my_graph.size(); i++)
            distances[my_graph[source][i]] = my_graph[source][i];
     
        return distances;
    }
     
    #endif
    Le premier fichier contient deux fonctions une fonction qui permet de calculer des valeurs pour la deuxi�me qui perform l'algorithme de johnson.

    Le main qui ne fait qu'appeler johnson et qui record le temps que �a prend .

    Le troisi�me qui contient la fonction qui perform l'algorithme de dijkstra.

    Voici l'erreur qui me rend fou : free(): invalid next size (fast): 0x0000000001d3e840 ***

    Le plus dingue : l'erreur intervient dans la boucle :

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    for(size_t i = 0; i < my_graph.size(); i++){
            std::vector<Tweight> shortest_paths_from_i = dijkstra<Tvertex, Tweight>(my_graph, i);
            for(size_t j = 0; j < my_graph.size(); ++j){
                std::cout << "i : " << i << " j  " << j << std::endl;
                //if(shortest_paths_from_i[j] == std::numeric_limits<Tweight>::max())
                //    distances[i][j] = shortest_paths_from_i[j];
                //else
                //    distances[i][j] = shortest_paths_from_i[j] + weights[j] - weights[i];
            }
        }
    Lorsque i = 3. Cependant (oui vous allez voir c'est marrant), si � la place de i je mets 0 tout va bien (j'applique my_graph.size() l'algo de dijkstra avec le node 0 comme node source, vu que c'est pas celui l� qui plantait �a me emble logique). Si � la place je mets 1 �a fonctionne, si � la place je mets 2 �a fonctionne une fois puis au second appel de dijkstra �a plante (alors que � la base c'est pas l'it�ration pour i = 2 qui plante), si je mets 3 �a fonctionne (c'est l'it�ration qui plantait...). Si je mets 4 5 6 ou 7 �a marche (mon petit exemple ne contient que 8 nodes).

    Quelq'un a t-il une id�e de ce qu'il se passe ? J'ai lu sur le forum et ailleurs que cette erreur survient lors de d�passements de m�moire, de double free, de tentative d'acc�s � de la m�moire non allou�e...

    Cependant ici l'it�ration qui plante de base c'est lorsque j'appelle dijkstra<Tvertex, Tweight>(my_graph, 3), qui ne plante pas dans si j'�cris dans ma boucle dijkstra<Tvertex, Tweight>(my_graph, 1 ou 2 ou 3 jusqu'� 7)

    Donc je me dis, peut-�tre que mes it�rations 0 ou 1 ou 2 provoquent des choses qui font que pour i = 3 �a plante (raison pour laquelle si je commence par la 3 �a ne plante pas par exemple). Cependant ma fonction dijkstra ne touchent pas � ses arguments d�clar�s "const" elle ne fait que retourner un std::vector<Tweight> (vous pouvez penser Tweight = double si vous voulez), du coup j'ai pas la moindre id�e de ce qu'il se passe...

    Merci encore � tous

  2. #2
    Expert confirm�
    Avatar de Luc Hermitte
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Ao�t 2003
    Messages
    5 296
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyr�n�es)

    Informations professionnelles :
    Activit� : D�veloppeur informatique
    Secteur : A�ronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Ao�t 2003
    Messages : 5 296
    Par d�faut
    Je vois des tailles employ�es qui ne correspondent pas � celles de l'objet manipul�. Pour moi que la matrice soit carr�e m�rite un assert pour le clarifier.

    Sinon, ton probl�me est un boulot pour valgrind, ou mieux le mode sanatize=address de clang (les derniers gcc l'ont aussi maintenant). Passer ta SL en mode check� peut �tre pas mal aussi.
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne r�ponds � aucune question technique par le biais de ce m�dia. Et de toutes fa�ons, ma BAL sur dvpz est pleine...

  3. #3
    Membre confirm�
    Homme Profil pro
    �tudiant
    Inscrit en
    Mars 2014
    Messages
    126
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activit� : �tudiant

    Informations forums :
    Inscription : Mars 2014
    Messages : 126
    Par d�faut
    Bonsoir et merci Monsieur Hermitte, des tailles employ�es qui ne correspondent pas � l'objet manipul� ? Puis-je savoir o� ? car c'est le premier truc que j'ai cherch� � v�rifier, j'ai tout print avant la derni�re boucle que j'ai montr� (celle dans laquelle on appelle dijkstra) et jusque l� le graphe contient exactement ce qu'il doit contenir, il fait une taille de 8 par 8. Est-ce que vous avez un tuto simple pour valgrind ? Je suis assez press� avec ce projet je voudrais bien trouver l'erreur rapidement.

    Merci encore

  4. #4
    Expert confirm�
    Avatar de Luc Hermitte
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Ao�t 2003
    Messages
    5 296
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyr�n�es)

    Informations professionnelles :
    Activit� : D�veloppeur informatique
    Secteur : A�ronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Ao�t 2003
    Messages : 5 296
    Par d�faut
    Typiquement, entre la ligne 46 et 47 du premier fichier, cela m�rite un
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    assert(copy_graph[i].size() > my_graph.size());
    Je n'ai pas tout regard�, mais s'il doit y avoir d'autres "�vidences" du genre, les �noncer clairement n'est jamais une perte de temps -- un coll�gue avait des probl�mes similaires il y a une 10aines de jours, et ... il a pu constater l'efficacit� du bestio pour trouver l'endroit o� ce qu'il croyait �tre vrai ne l'�tait pas.

    Et si c'est �vident, raison de plus pour l'affirmer. En tant que relecteur qui ne connait rien au probl�me voir une taille sortie de nulle part utilis�e ailleurs choque. BTW, si l'objectif est de changer le dernier �l�ment de la colonne, un
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    copy_graph[i].back() = k_half;
    suffirait.

    Pour valgrind, il suffit de le lancer et de traiter les probl�mes dans l'ordre. Si le programme se lan�ait avec "./prog param1 -o param2", il suffit de faire "valgrind ./prog param1 -o param2". C'est d�j� un bon d�but (on peut aussi lui dire de s'arr�ter � la premi�re erreur rencontr�e et de passer en debugage � ce moment l�). Mais si c'est bien un probl�me d'�criture hors bornes (ce que je soup�onne vu que je ne vois pas de trace de pointeur brut dans le code donn�), le mode sanatize=address peut �tre bien plus riche en info.

    Et ne pas n�gliger la 3e alternative qui consiste � passer la STL en mode check�. J'insiste. Valgrind, tout le monde en parle. Mais �a g�n�re beaucoup de bruit, les contextes ne sont jamais clairs si on ne force pas le debug � la premi�re erreur trouv�e, et �a peut �tre bien trop lent. Alors qu'il y a des outils qui vont faire du failfast et permettre de disposer simplement du contexte lors de l'ex�cution (typiquement un coredump)
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne r�ponds � aucune question technique par le biais de ce m�dia. Et de toutes fa�ons, ma BAL sur dvpz est pleine...

  5. #5
    Membre confirm�
    Homme Profil pro
    �tudiant
    Inscrit en
    Mars 2014
    Messages
    126
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activit� : �tudiant

    Informations forums :
    Inscription : Mars 2014
    Messages : 126
    Par d�faut
    Rebonsoir, j'ai commenc� par tester ton assert et tu avais raison, �a a p�t�. Je ne sais pas trop pourquoi sans doute je m'y suis mal pris. Ca ne change pas vraiment la derni�re colonne, �a en rajoute une. Donc comme back() �a touche � la derni�re colonne existante je crois pas que �a va marcher. Mais merci

  6. #6
    Expert confirm�
    Avatar de Luc Hermitte
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Ao�t 2003
    Messages
    5 296
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyr�n�es)

    Informations professionnelles :
    Activit� : D�veloppeur informatique
    Secteur : A�ronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Ao�t 2003
    Messages : 5 296
    Par d�faut
    Pour rajouter une colonne, c'est push_back() alors.
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne r�ponds � aucune question technique par le biais de ce m�dia. Et de toutes fa�ons, ma BAL sur dvpz est pleine...

+ R�pondre � la discussion
Cette discussion est r�solue.

Discussions similaires

  1. free(): invalid next size (normal)
    Par Heimdall dans le forum C
    R�ponses: 18
    Dernier message: 02/01/2008, 11h25
  2. [JDBC] Erreur tr�s bizarre dans ExecuteQuery
    Par boudou dans le forum JDBC
    R�ponses: 6
    Dernier message: 17/03/2006, 18h33
  3. diff�rence reload et location + pb tr�s bizarre pour experts
    Par grinder59 dans le forum G�n�ral JavaScript
    R�ponses: 21
    Dernier message: 09/01/2006, 12h05
  4. Probl�me tr�s bizarre avec COUNT
    Par Nomade95000 dans le forum Langage SQL
    R�ponses: 4
    Dernier message: 13/10/2005, 14h12
  5. R�ponses: 4
    Dernier message: 28/09/2002, 00h00

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo