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 :

malloc débloque, au tableaux !


Sujet :

C

  1. #1
    Membre éprouvé
    Avatar de Luke spywoker
    Homme Profil pro
    Etudiant informatique autodidacte
    Inscrit en
    Juin 2010
    Messages
    1 077
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Etudiant informatique autodidacte

    Informations forums :
    Inscription : Juin 2010
    Messages : 1 077
    Par défaut malloc débloque, au tableaux !
    Salut les C,

    Je voulais faire évoluer ma library complémentaire a SDL2 de génération et d'animation de forme: SDL2_gfxutils.

    Et je suis confronter a un problème la plupart des fonctions de génération provoque une erreur de malloc (enfin j'utilise calloc mais gdb rapporte malloc) quand je fais un tableaux de plusieurs formes: pourtant lors du développement j'ai fais des tableaux mais fonctionnaient.
    Pour rentrez dans le détails j'ai remarquer que quand j'utilise une variable a la place d'une valeur fixe ma library débloque de malloc...

    Un bout de code pour montrer:
    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
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    #include <SDL2/SDL.h>
    #include <SDL2/SDL2_gfxPrimitives.h>
    #include <SDL2_gfxutils.h>
     
    #include <stdio.h>
     
    #include <stdlib.h>
    #include <stdbool.h>
     
    #include <unistd.h>
     
    #include <time.h>
     
    bool loop ;
     
    #define set_loop(x) loop=x ;
     
    #define WIDTH  (int16_t) 800
    #define HEIGHT (int16_t) 600
     
     
    #define CENTER_X (int16_t) 800/2
    #define CENTER_Y (int16_t) 600/2
     
    #define ITERATIONS 360/12
     
     
    int sdl_init(uint32_t flags) ;
    SDL_Window* sdl_create_window(const char *title,int screen_x_pos, int screen_y_pos, int width, int height,int flags) ;
    SDL_Renderer* sdl_create_renderer(SDL_Window *window,int index,int flags) ;
     
    void get_events(void) ;
    void clear(SDL_Renderer *pRenderer,uint8_t bg_red, uint8_t bg_green, uint8_t bg_blue,uint8_t bg_a) ;
    void display(SDL_Renderer *pRenderer) ;
    void update(SDL_Window *pWindow) ;
    void clean_up(SDL_Renderer *pRenderer, SDL_Window *pWindow) ;
     
    // $ gcc -g -Wall main.c -o prg -lm -lSDL2  -lSDL2_gfxutils
     
     
    int main(void) {
     
      /** SDL2 initialized: */
      if (sdl_init(SDL_INIT_VIDEO) != 0 ) {
        fprintf(stdout,"SDL initialize failed (%s)\n",SDL_GetError());
        return -1;
      }
     
      /** Window creation: */
      SDL_Window* pWindow = NULL;
      pWindow = sdl_create_window("SDL2 2D Creation Template", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 800, 600, SDL_WINDOW_SHOWN) ;
     
      if( pWindow == NULL) {
        fprintf(stderr,"Windows creation error: %s\n",SDL_GetError());
        return -1 ;
      }
     
      /** Renderer creation. */
      SDL_Renderer *pRenderer  ;
      if ((pRenderer = sdl_create_renderer(pWindow,-1,SDL_RENDERER_ACCELERATED)) == NULL) {
        fprintf(stderr,"SDL Renderer creating error (%s)\n",SDL_GetError());
        return -1;
      }
     
      srand(time(NULL)) ;
     
      int c ;
     
      Polygon polygons[80] ;
     
      Pixel center ;
     
      center.x = 800/2 ;
      center.y = 600/2 ; 
     
      for (c=0 ; c < 80 ; c++) {
     
        int side ;
        while ((side = rand() % 32) < 3) {} ; 
     
        polygons[c] = generate_corners_rounded_polygon(side, c*2.0, center, 0) ;
     
        set_form_color(&polygons[c], rand() % 256, rand() % 256, rand() % 256, 255) ;
     
      }
     
      set_loop(true) ;
      c=0  ;
      while (loop) {
     
     
     
          clear(pRenderer,0, 0, 0, 255) ;
     
     
          for (c=0 ; c < 80 ; c++) { 
            display_polygon(pRenderer, polygons[c]) ;
          }
     
          display(pRenderer);
          update(pWindow);
     
          get_events() ;
     
          usleep(125000) ;
      }
     
      /** Freeing the polygons. **/
      for (c=0 ; c < 80 ; c++) {
     
         free(polygons[c].coords.x) ;
         free(polygons[c].coords.y) ;./prg
    *** Error in `./prg': munmap_chunk(): invalid pointer: 0x000000000331fda0 ***
    Abandon (core dumped)
     
     
      }
     
      clean_up(pRenderer, pWindow) ;
     
      SDL_Quit();
     
      return 0;
     
    }
     
     
     
     
    int sdl_init(uint32_t flags) {
      /**
       * flags:
       * SDL_INIT_TIMER               timer subsystem
       * SDL_INIT_AUDIO               audio subsystem
       * SDL_INIT_VIDEO                   video subsystem
       * SDL_INIT_JOYSTICK            joystick subsystem
       * SDL_INIT_HAPTIC              haptic (force feedback) subsystem
       * SDL_INIT_GAMECONTROLLER  controller subsystem
       * SDL_INIT_EVENTS              events subsystem
       * SDL_INIT_EVERYTHING          all of the above subsystems
       * SDL_INIT_NOPARACHUTE         don't catch fatal signals
       *******************************************************************/
       return SDL_Init(flags) ;
    }
     
    SDL_Window* sdl_create_window(const char *title,int screen_x_pos, int screen_y_pos, int width, int height,int flags) {
     
      /**
       * screen_x_pos && screen_y_pos == SDL_WINDOWPOS_CENTERED or SDL_WINDOWPOS_UNDEFINED ;
       *
       * flags :
       * SDL_WINDOW_FULLSCREEN                  fullscreen window
       * SDL_WINDOW_FULLSCREEN_DESKTOP      fullscreen window at the current desktop resolution
       * SDL_WINDOW_OPENGL                      window usable with OpenGL context
       * SDL_WINDOW_HIDDEN                      window is not visible
       * SDL_WINDOW_BORDERLESS                  no window decoration
       * SDL_WINDOW_RESIZABLE                   window can be resized
       * SDL_WINDOW_MINIMIZED                   window is minimized
       * SDL_WINDOW_MAXIMIZED                   window is maximized
       * SDL_WINDOW_INPUT_GRABBED           window has grabbed input focus
       * SDL_WINDOW_ALLOW_HIGHDPI           window should be created in high-DPI mode if supported (>= SDL 2.0.1)
       **********************************************************************************************************/
     
      return SDL_CreateWindow(title, screen_x_pos, screen_y_pos, width, height, flags) ;
    }
     
    SDL_Renderer* sdl_create_renderer(SDL_Window *window,int index,int flags) {
     
       /**
        * index : the index of the rendering driver to initialize, or -1 to initialize the first one supporting the requested flags
        *
        * flags:
        * SDL_RENDERER_SOFTWARE                 the renderer is a software fallback
        * SDL_RENDERER_ACCELERATED          the renderer uses hardware acceleration
        * SDL_RENDERER_PRESENTVSYNC         present is synchronized with the refresh rate
        * SDL_RENDERER_TARGETTEXTURE        the renderer supports rendering to texture
        *
        * Note that providing no flags gives priority to available SDL_RENDERER_ACCELERATED renderer.
        **********************************************************************************************/
     
       return SDL_CreateRenderer(window,(index != -1) ? index : -1  ,(flags == 0) ? SDL_RENDERER_ACCELERATED : flags ) ;
    }
     
    void get_events(void) {
     
      SDL_Event event;
     
      while (SDL_PollEvent(&event)) { /** Get user events */
     
        switch(event.type) {
     
          case SDL_QUIT: /** User quit the application. */
    	    set_loop(false) ;
            break;
     
     
        }
      }
     
      return ;
    }
     
    void clear(SDL_Renderer *pRenderer,uint8_t bg_red, uint8_t bg_green, uint8_t bg_blue,uint8_t bg_a) {
      SDL_SetRenderDrawColor(pRenderer, bg_red, bg_green, bg_blue, bg_a) ;
      SDL_RenderClear(pRenderer);
    }./prg
    *** Error in `./prg': munmap_chunk(): invalid pointer: 0x000000000331fda0 ***
    Abandon (core dumped)
     
     
    void display(SDL_Renderer *pRenderer) {
      SDL_RenderPresent(pRenderer);
    }
     
    void update(SDL_Window *pWindow) {
      SDL_UpdateWindowSurface(pWindow);
    }
     
    void clean_up(SDL_Renderer *pRenderer, SDL_Window *pWindow) {
      SDL_DestroyRenderer(pRenderer);
      SDL_DestroyWindow(pWindow);
    }
    Le programme plante ???

    ./prg
    *** Error in `./prg': munmap_chunk(): invalid pointer: 0x000000000331fda0 ***
    Abandon (core dumped)
    Si je ne garde que la boucle de génération de polygones avec gdb ca donne ça:
    $ gdb prg
    GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.2) 7.7.1
    Copyright (C) 2014 Free Software Foundation, Inc.
    License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
    This is free software: you are free to change and redistribute it.
    There is NO WARRANTY, to the extent permitted by law. Type "show copying"
    and "show warranty" for details.
    This GDB was configured as "x86_64-linux-gnu".
    Type "show configuration" for configuration details.
    For bug reporting instructions, please see:
    <http://www.gnu.org/software/gdb/bugs/>.
    Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.
    For help, type "help".
    Type "apropos word" to search for commands related to "word"...
    Reading symbols from prg...done.
    (gdb) run
    Starting program: /home/edward/Bureau/prg
    [Thread debugging using libthread_db enabled]
    Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

    Program received signal SIGSEGV, Segmentation fault.
    0x00007ffff7586e2c in __GI___libc_free (mem=0x603cb0)
    at malloc.c:2945
    2945 malloc.c: Aucun fichier ou dossier de ce type.
    (gdb) where
    #0 0x00007ffff7586e2c in __GI___libc_free (mem=0x603cb0)
    at malloc.c:2945
    #1 0x00007ffff78cc2f7 in generate_corners_rounded_polygon (
    sides=<optimized out>, radius=<optimized out>, center=...,
    orientation=0) at ./Forms/polygon.c:283
    #2 0x0000000000400c8e in main () at main.c:82
    (gdb) quit
    A debugging session is active.

    Inferior 1 [process 15503] will be killed.

    Quit anyway? (y or n) y
    Si l'on remplace par certaines fonctions comme generate_polygon_radius(...) et bien cela fonctionne et aussi si vous utilisez un seule polygone ???

    Merci pour votre aide précieuse.

  2. #2
    Membre Expert
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Par défaut
    Je ne vois aucune allocation dans ce code. Fournis-nous un exemple minimal qui plante qu'on puisse y voir clair.

    Utilise valgrind pour tout ce qui touche aux allocations dynamiques.

  3. #3
    Expert confirmé
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 751
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 751
    Par défaut
    Citation Envoyé par Matt_Houston Voir le message
    Je ne vois aucune allocation dans ce code. Fournis-nous un exemple minimal qui plante qu'on puisse y voir clair.

    Utilise valgrind pour tout ce qui touche aux allocations dynamiques.
    Normal c'est la bibliothèque SDL qui fait les allocations

    Dynamically allocated memory.

    All the forms generating functions allocate dynamically the needed space for the Coords member.

    So that you must free the x and y members from the Coords type wenn you no more need the Polygon or derivated types.

    The Coords type

    The Coords type in only used internally to be a member of the Polygon type.

    typedef struct Coords_ {
    int16_t *x ;
    int16_t *y ;
    } Coords ;

    note: The pointers x and :cmember`y` are adapt to the SDL2_gfx standart, from int16_t and are arrays from coordinates.

    Warning Freeing coordinates arrays x and y.

    After using a Form, Wenn you do not need it in the future, you must free the coords members x and y arrays.

    Because every form generating function allocte dynamically the needed space for this arrays.
    note: By using the *_new ending transformations functions you can free the coordinates arays by setting the freeing_from argument on true.

  4. #4
    Membre éprouvé
    Avatar de Luke spywoker
    Homme Profil pro
    Etudiant informatique autodidacte
    Inscrit en
    Juin 2010
    Messages
    1 077
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Etudiant informatique autodidacte

    Informations forums :
    Inscription : Juin 2010
    Messages : 1 077
    Par défaut
    Merci a foetus pour la remise en forme d'intérêt minimal porté au problème,

    Excuse moi je ne veut pas te manquer de respect, Matt_Houston, et merci pour le conseil.
    Si j'utilise dmalloc au lieu de valgrind (que je ne connais pas contrairement a dmalloc) ca ira aussi au niveau des allocations dynamiques ?

    Pour te satisfaire voici le code de la fonction en question (ce n'est pas la seule qui a le même problème):

    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
     
    Polygon generate_corners_rounded_polygon(int32_t sides, double radius, Pixel center, double orientation) {
      /** Generated an polygon which corners are arcs
        * which size is in relationship to the number
        * of sides of the polygon.
        *********************************************/
     
      if (sides < 3) {
        fprintf(stderr,"Wrong sides number argument: sides must be >= 3 !\n") ;
        exit(EXIT_FAILURE) ;
      }
     
     
      int32_t c, i, cc ;
     
      double offset = 360.0/sides  ;
      double angle  = offset      ;
     
      /** Generate a polygon for the place of the arcs centers: **/
      Polygon arcs_centers = generate_polygon_radius(sides, radius, center, angle) ;
     
     
      Arc arcs[arcs_centers.count] ;
      for (c=0 ; c < arcs_centers.count ; c++) {
        /** Generate the polygon corners arcs. **/
        Pixel tmp_center ;
     
        tmp_center.x = arcs_centers.coords.x[c] ;
        tmp_center.y = arcs_centers.coords.y[c] ;
     
        arcs[c]=generate_circle_arc(radius, tmp_center, angle + (offset/2.0), offset) ;
     
        angle += offset ;
      }
     
      /** Polygon to return: **/
      Polygon rounded_polygon ;
     
      rounded_polygon.count = arcs_centers.count * arcs[0].count ;
     
      rounded_polygon.coords.x = calloc(rounded_polygon.count, sizeof(int16_t) ) ;
      rounded_polygon.coords.y = calloc(rounded_polygon.count, sizeof(int16_t) ) ;
     
      /** Generate the rounded corners polygon: **/
      i=0 ;
      for (c=0 ; c < arcs_centers.count ; c++) {
        /** We want to add all the arcs to the polygon. **/
        for (cc=0 ; cc < arcs[c].count ; cc++) {
          /** We add each pixel from the arcs to the polygon. **/
          Pixel tmp, res ;
     
          tmp.x = arcs[c].coords.x[cc] ;
          tmp.y = arcs[c].coords.y[cc] ;
     
          /** Even with an orientation offset. **/
          res = rotate(center,orientation,tmp) ;
     
          rounded_polygon.coords.x[i] = res.x ;
          rounded_polygon.coords.y[i] = res.y ;
     
          i++ ;
        }
      }
     
     
      /** Freeing temporary needed coordinates arrays. **/
     
      free(arcs_centers.coords.x) ;
      free(arcs_centers.coords.y) ;
     
      for (c=0 ; c < arcs_centers.count ; c++) {
        free(arcs[c].coords.x) ;
        free(arcs[c].coords.y) ;
      }
     
     
      return rounded_polygon ;
     
    }
    NOTE: Pour les 2 appels de fonctions inconnus sur mon site il y a un lien vers le github de SDL2_gfxutils.

    PS: Au passage pour le contrôle (sides < 3) je pourrai appeler abort() a la place d'exit() ?

    On avance pas trop car même si je dmalloc le truc je ne pense pas avancer car si vous comptez le nombre d'allocations des membres du tableau réussis il y en aura quand même quelques unes ?

    Merci pour votre aide.

  5. #5
    Membre Expert
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Par défaut
    Alors dans le respect également et par rapport à ton premier message : je ne comprends pas ta démarche, tu demandes de l'aide sur un bug d'allocation en postant plus de 200 lignes de code où ne figurent même pas :

    • les définitions des types que tu utilises ;
    • les méthodes d'allocation dynamique employées.

    Certains sont peut-être disposés à retourner le repo d'une bibliothèque tierce pour savoir comment fonctionne ton code, pas moi. Je ne viens pas ici pour occuper mon temps et j'ai autre chose à faire.


    Pour en revenir à comment trouver l'origine de ton souci, je n'ai jamais utilisé dmalloc mais j'insiste vraiment sur la puissance de valgrind et de son module memcheck. J'en recommande sans réserve l'usage aux programmeurs C de tout niveau. Malheureusement il n'existe pas de version pour Windows.

    Donc pour trouver l'origine de ton souci, on pourrait peut-être :
    • éliminer de ton projet tout ce qu'il est possible d'éliminer en conservant le bug ;
    • overrider les appels à free avec quelque chose du style de :
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      7
      #include <assert.h>
       
      #define free_debug(p) { \
          assert(p && "pointed area has already been freed"); \
          free(p); \
          p = NULL; \
      }
    • passer l'exécutable à la moulinette valgrind.


    Citation Envoyé par Luke spywoker Voir le message
    PS: Au passage pour le contrôle (sides < 3) je pourrai appeler abort() a la place d'exit() ?
    C'est à toi de voir, sachant qu'abort génère SIGABRT et ne garantit pas le nettoyage des handles à la exit. Si tu as spécifié des callbacks à atexit, elles ne seront pas non plus exécutées. C'est une stratégie différente.

  6. #6
    Membre éprouvé
    Avatar de Luke spywoker
    Homme Profil pro
    Etudiant informatique autodidacte
    Inscrit en
    Juin 2010
    Messages
    1 077
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Etudiant informatique autodidacte

    Informations forums :
    Inscription : Juin 2010
    Messages : 1 077
    Par défaut
    Le problème est résolu et la reécriture de la library est en bonne voix.
    Merci pour vos réponses les gars.

    Il y'aura du sacré changement dans la library...

    Certains sont peut-être disposés à retourner le repo d'une bibliothèque tierce pour savoir comment fonctionne ton code
    C'est chacun comme il le veut, c'est ton choix et je le respecte et je suis désolé de t'avoir offenser, peut-être que je vanterai valgrind un jours qui sait...???

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 4
    Dernier message: 13/02/2011, 11h11
  2. Réponses: 3
    Dernier message: 17/03/2008, 10h54
  3. Réponses: 4
    Dernier message: 21/03/2006, 04h55
  4. Réponses: 4
    Dernier message: 03/12/2002, 16h47
  5. Les tableaux en PL/SQL
    Par GRUMLY dans le forum PL/SQL
    Réponses: 5
    Dernier message: 12/08/2002, 18h10

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