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

Langage C++ Discussion :

Libérer le pointeur d'une class parent dans une class enfant?


Sujet :

Langage C++

  1. #1
    Membre actif Avatar de Narann
    Inscrit en
    Juin 2007
    Messages
    140
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 140
    Points : 211
    Points
    211
    Par défaut [RESOLU]Libérer le pointeur d'une class parent dans une class enfant?
    Bonjours à tous,
    Je suis en train de matter les sources d'un code et il y à quelque chose que je trouve bizarre. Voici le problème:

    Texture.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    class CTexture
    {
    public:
        virtual ~CTexture();
     
        [...]
     
    protected:
        LPRICETEXTURE   m_pTexture; //C'est ça qui nous intéresse
    };
    Texture.cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    CTexture::~CTexture(void)
    {
     //Il n'y a pas de free(m_pTexture); ici. Normal?
    }
    Et dans l'autre class, hérité de la classe précédente

    OGLTexture.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    class COGLTexture : public CTexture //elle hérite de la class CTexture
    {
        friend class COGLRenderTexture;
    public:
        ~COGLTexture();
     
        [...]
    };
    OGLTexture.cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    COGLTexture::~COGLTexture()
    {
        [...]
        free(m_pTexture);
        [...]
    }
    En gros, ce qui m'étonne, c'est que ce n'est pas la class CTexture qui "free" sont m_pTexture mais la class "héritière". Ça ne me semble pas correct.
    J'aurai plutôt écris les choses comme ça:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    COGLTexture::~COGLTexture()
    {
        [...]
        //free(m_pTexture); On vire le free ici
        [...]
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    CTexture::~CTexture(void)
    {
        free(m_pTexture); //Et je le met ici
    }
    Qu'en pensez vous?

    Merci d'avance pour vos avis éclairés!

  2. #2
    Membre confirmé Avatar de Lavock
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    560
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 560
    Points : 633
    Points
    633
    Par défaut
    Je pense q'un free en c++ c'est un peu limite déjà...
    Et même si un free() était bel et bien valable, c'est limite absurde... Sûrement quelqu'un qui n'était pas au courant que un destructeur virtuelle d'une classe mère est lui aussi appelé >< !

    Edit : à y réfléchir, selon ce que font les autres classes filles ou même ce qui est contenue dans [...], ça peut "avoir" une raison... Mais c'est leak-like quand même... Une approche leak-proof aurait peut-être était d'utiliser un smart-pointer dans se cas... Tout de même assez stupide de faire sans...

    Au passage, pour être un minimum valable, il faut que se soit spécifier dans la doc et surtout que la classe mère soit abstraite.
    The mark of the immature man is that he wants to die nobly for a cause, while the mark of the mature man is that he wants to live humbly for one.
    --Wilhelm Stekel

  3. #3
    Membre actif Avatar de Narann
    Inscrit en
    Juin 2007
    Messages
    140
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 140
    Points : 211
    Points
    211
    Par défaut
    Mmmh. Intéressant. Merci pour la réponse.
    Sûrement quelqu'un qui n'était pas au courant que un destructeur virtuelle d'une classe mère est lui aussi appelé >< !
    Je le suis aussi... Tu peut préciser?

    Je me permet de copier tout le code si ça peut rendre les choses plus claire:
    Texture.h
    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
    /*
    Copyright (C) 2003 Rice1964
     
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
    as published by the Free Software Foundation; either version 2
    of the License, or (at your option) any later version.
     
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
     
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
     
    */
     
     
    #ifndef __SURFACEHANDLER_H__
    #define __SURFACEHANDLER_H__
     
    #include "typedefs.h"
     
    /////////////// Define a struct to use as
    ///////////////  storage for all the surfaces
    ///////////////  created so far.
    class CTexture;
     
    typedef struct {
        unsigned short int  dwWidth;            // Describes the width of the real texture area. Use lPitch to move between successive lines
        unsigned short int  dwHeight;           // Describes the height of the real texture area
        unsigned short int  dwCreatedWidth;     // Describes the width of the created texture area. Use lPitch to move between successive lines
        unsigned short int  dwCreatedHeight;    // Describes the height of the created texture area
        int        lPitch;             // Specifies the number of bytes on each row (not necessarily bitdepth*width/8)
        void        *lpSurface;         // Pointer to the top left pixel of the image
    } DrawInfo;
     
     
    enum TextureFmt {
        TEXTURE_FMT_A8R8G8B8,
        TEXTURE_FMT_A4R4G4B4,
        TEXTURE_FMT_UNKNOWN,
    };
     
    enum TextureUsage {
        AS_NORMAL,
        AS_RENDER_TARGET,
        AS_BACK_BUFFER_SAVE,
    };
     
    class CTexture
    {
    public:
        virtual ~CTexture();
     
        uint32      m_dwWidth;          // The requested Texture w/h
        uint32      m_dwHeight;
     
        unsigned int        m_dwCreatedTextureWidth;    // What was actually created
        unsigned int        m_dwCreatedTextureHeight;
     
        float       m_fXScale;      // = m_dwCorrectedWidth/m_dwWidth
        float       m_fYScale;      // = m_dwCorrectedHeight/m_dwWidth
     
        bool        m_bScaledS;
        bool        m_bScaledT;
     
        bool        m_bClampedS;
        bool        m_bClampedT;
     
        bool        m_bIsEnhancedTexture;
     
        TextureUsage    m_Usage;
     
        virtual void ScaleImageToSurface(bool scaleS=true, bool scaleT=true);
        virtual void ClampImageToSurfaceS();
        virtual void ClampImageToSurfaceT();
     
        virtual LPRICETEXTURE GetTexture() { return m_pTexture; }
     
        uint32          GetPixelSize();
        TextureFmt      GetSurfaceFormat(void); // Surface pixel format...
        inline void     SetOthersVariables(void)
        {
            m_bClampedS = m_bScaledS = (m_dwWidth == m_dwCreatedTextureWidth);
            m_bClampedT = m_bScaledT = (m_dwHeight == m_dwCreatedTextureHeight);
        }
     
        // Provides access to "surface"
        virtual bool StartUpdate(DrawInfo *di)=0;
        virtual void EndUpdate(DrawInfo *di)=0;
     
        virtual void RestoreAlphaChannel(void); // Restore Alpha channel from RGB channel
     
    protected:
        CTexture(uint32 dwWidth, uint32 dwHeight, TextureUsage usage = AS_NORMAL);
        LPRICETEXTURE   m_pTexture;
        TextureFmt      m_dwTextureFmt;
    };
     
    #endif
    Texture.cpp
    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
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    /*
    Copyright (C) 2003 Rice1964
     
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
    as published by the Free Software Foundation; either version 2
    of the License, or (at your option) any later version.
     
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
     
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
     
    */
     
    #include "TextureManager.h"
     
     
    //////////////////////////////////////////
    // Constructors / Deconstructors
     
    // Probably shouldn't need more than 4096 * 4096
     
    CTexture::CTexture(uint32 dwWidth, uint32 dwHeight, TextureUsage usage) :
        m_dwWidth(dwWidth),
        m_dwHeight(dwHeight),
        m_dwCreatedTextureWidth(dwWidth),
        m_dwCreatedTextureHeight(dwHeight),
        m_fXScale(1.0f),
        m_fYScale(1.0f),
        m_bScaledS(false),
        m_bScaledT(false),
        m_bClampedS(false),
        m_bClampedT(false),
        m_bIsEnhancedTexture(false),
        m_Usage(usage),
            m_pTexture(NULL),
            m_dwTextureFmt(TEXTURE_FMT_A8R8G8B8)
    {
        // fix me, do something here
    }
     
     
    CTexture::~CTexture(void)
    {
    }
     
    TextureFmt CTexture::GetSurfaceFormat(void)
    {
        if (m_pTexture == NULL)
            return TEXTURE_FMT_UNKNOWN;
        else
            return m_dwTextureFmt;
    }
     
    uint32 CTexture::GetPixelSize()
    {
        if( m_dwTextureFmt == TEXTURE_FMT_A8R8G8B8 )
            return 4;
        else
            return 2;
    }
     
     
    // There are reasons to create this function. D3D and OGL will only create surface of width and height
    // as 2's pow, for example, N64's 20x14 image, D3D and OGL will create a 32x16 surface.
    // When we using such a surface as D3D texture, and the U and V address is for the D3D and OGL surface
    // width and height. It is still OK if the U and V addr value is less than the real image within
    // the D3D surface. But we will have problems if the U and V addr value is larger than it, or even
    // large then 1.0.
    // In such a case, we need to scale the image to the D3D surface dimension, to ease the U/V addr
    // limition
    void CTexture::ScaleImageToSurface(bool scaleS, bool scaleT)
    {
        uint8 g_ucTempBuffer[1024*1024*4];
     
        if( scaleS==false && scaleT==false) return;
     
        // If the image is not scaled, call this function to scale the real image to
        // the D3D given dimension
     
        uint32 width = scaleS ? m_dwWidth : m_dwCreatedTextureWidth;
        uint32 height = scaleT ? m_dwHeight : m_dwCreatedTextureHeight;
     
        uint32 xDst, yDst;
        uint32 xSrc, ySrc;
     
        DrawInfo di;
     
        if (!StartUpdate(&di))
        {
            return;
        }
     
        int pixSize = GetPixelSize();
     
        // Copy across from the temp buffer to the surface
        switch (pixSize)
        {
        case 4:
            {
                memcpy((uint8*)g_ucTempBuffer, (uint8*)(di.lpSurface), m_dwHeight*m_dwCreatedTextureWidth*4);
     
                uint32 * pDst;
                uint32 * pSrc;
     
                for (yDst = 0; yDst < m_dwCreatedTextureHeight; yDst++)
                {
                    // ySrc ranges from 0..m_dwHeight
                    // I'd rather do this but sometimes very narrow (i.e. 1 pixel)
                    // surfaces are created which results in  /0...
                    //ySrc = (yDst * (m_dwHeight-1)) / (d3dTextureHeight-1);
                    ySrc = (uint32)((yDst * height) / m_dwCreatedTextureHeight+0.49f);
     
                    pSrc = (uint32*)((uint8*)g_ucTempBuffer + (ySrc * m_dwCreatedTextureWidth * 4));
                    pDst = (uint32*)((uint8*)di.lpSurface + (yDst * di.lPitch));
     
                    for (xDst = 0; xDst < m_dwCreatedTextureWidth; xDst++)
                    {
                        xSrc = (uint32)((xDst * width) / m_dwCreatedTextureWidth+0.49f);
                        pDst[xDst] = pSrc[xSrc];
                    }
                }
            }
     
            break;
        case 2:
            {
                memcpy((uint8*)g_ucTempBuffer, (uint8*)(di.lpSurface), m_dwHeight*m_dwCreatedTextureWidth*2);
     
                uint16 * pDst;
                uint16 * pSrc;
     
                for (yDst = 0; yDst < m_dwCreatedTextureHeight; yDst++)
                {
                    // ySrc ranges from 0..m_dwHeight
                    ySrc = (yDst * height) / m_dwCreatedTextureHeight;
     
                    pSrc = (uint16*)((uint8*)g_ucTempBuffer + (ySrc * m_dwCreatedTextureWidth * 2));
                    pDst = (uint16*)((uint8*)di.lpSurface + (yDst * di.lPitch));
     
                    for (xDst = 0; xDst < m_dwCreatedTextureWidth; xDst++)
                    {
                        xSrc = (xDst * width) / m_dwCreatedTextureWidth;
                        pDst[xDst] = pSrc[xSrc];
                    }
                }
            }
            break;
     
        }
     
        EndUpdate(&di);
     
        if( scaleS ) m_bScaledS = true;
        if( scaleT ) m_bScaledT = true;
    }
     
    void CTexture::ClampImageToSurfaceS()
    {
        if( !m_bClampedS && m_dwWidth < m_dwCreatedTextureWidth )
        {       
            DrawInfo di;
            if( StartUpdate(&di) )
            {
                if(  m_dwTextureFmt == TEXTURE_FMT_A8R8G8B8 )
                {
                    for( uint32 y = 0; y<m_dwHeight; y++ )
                    {
                        uint32* line = (uint32*)((uint8*)di.lpSurface+di.lPitch*y);
                        uint32 val = line[m_dwWidth-1];
                        for( uint32 x=m_dwWidth; x<m_dwCreatedTextureWidth; x++ )
                        {
                            line[x] = val;
                        }
                    }
                }
                else
                {
                    for( uint32 y = 0; y<m_dwHeight; y++ )
                    {
                        uint16* line = (uint16*)((uint8*)di.lpSurface+di.lPitch*y);
                        uint16 val = line[m_dwWidth-1];
                        for( uint32 x=m_dwWidth; x<m_dwCreatedTextureWidth; x++ )
                        {
                            line[x] = val;
                        }
                    }
                }
                EndUpdate(&di);
            }
        }
        m_bClampedS = true;
    }
     
    void CTexture::ClampImageToSurfaceT()
    {
        if( !m_bClampedT && m_dwHeight < m_dwCreatedTextureHeight )
        {
            DrawInfo di;
            if( StartUpdate(&di) )
            {
                if(  m_dwTextureFmt == TEXTURE_FMT_A8R8G8B8 )
                {
                    uint32* linesrc = (uint32*)((uint8*)di.lpSurface+di.lPitch*(m_dwHeight-1));
                    for( uint32 y = m_dwHeight; y<m_dwCreatedTextureHeight; y++ )
                    {
                        uint32* linedst = (uint32*)((uint8*)di.lpSurface+di.lPitch*y);
                        for( uint32 x=0; x<m_dwCreatedTextureWidth; x++ )
                        {
                            linedst[x] = linesrc[x];
                        }
                    }
                }
                else
                {
                    uint16* linesrc = (uint16*)((uint8*)di.lpSurface+di.lPitch*(m_dwHeight-1));
                    for( uint32 y = m_dwHeight; y<m_dwCreatedTextureHeight; y++ )
                    {
                        uint16* linedst = (uint16*)((uint8*)di.lpSurface+di.lPitch*y);
                        for( uint32 x=0; x<m_dwCreatedTextureWidth; x++ )
                        {
                            linedst[x] = linesrc[x];
                        }
                    }
                }
                EndUpdate(&di);
            }
        }
        m_bClampedT = true;
    }
     
    void CTexture::RestoreAlphaChannel(void)
    {
        DrawInfo di;
     
        if ( StartUpdate(&di) )
        {
            uint32 *pSrc = (uint32 *)di.lpSurface;
            int lPitch = di.lPitch;
     
            for (uint32 y = 0; y < m_dwHeight; y++)
            {
                uint32 * dwSrc = (uint32 *)((uint8 *)pSrc + y*lPitch);
                for (uint32 x = 0; x < m_dwWidth; x++)
                {
                    uint32 dw = dwSrc[x];
                    uint32 dwRed   = (uint8)((dw & 0x00FF0000)>>16);
                    uint32 dwGreen = (uint8)((dw & 0x0000FF00)>>8 );
                    uint32 dwBlue  = (uint8)((dw & 0x000000FF)    );
                    uint32 dwAlpha = (dwRed+dwGreen+dwBlue)/3;
                    dw &= 0x00FFFFFF;
                    dw |= (dwAlpha<<24);
     
                    /*
                    uint32 dw = dwSrc[x];
                    if( (dw&0x00FFFFFF) > 0 )
                        dw |= 0xFF000000;
                    else
                        dw &= 0x00FFFFFF;
                        */
                }
            }
            EndUpdate(&di);
        }
        else
        {
            //TRACE0("Cannot lock texture");
        }
    }
    OGLTexture.h
    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
    /*
    Copyright (C) 2003 Rice1964
     
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
    as published by the Free Software Foundation; either version 2
    of the License, or (at your option) any later version.
     
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
     
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
    */
     
    #ifndef _OGL_TEXTURE_H_
    #define _OGL_TEXTURE_H_
     
    #include <SDL_opengl.h>
     
    #include "TextureManager.h"
     
    class COGLTexture : public CTexture
    {
        friend class COGLRenderTexture;
    public:
        ~COGLTexture();
     
        bool StartUpdate(DrawInfo *di);
        void EndUpdate(DrawInfo *di);
     
        GLuint m_dwTextureName;
        GLuint m_glFmt;
    protected:
        friend class OGLDeviceBuilder;
        COGLTexture(uint32 dwWidth, uint32 dwHeight, TextureUsage usage = AS_NORMAL);
    };
     
     
    #endif
    OGLTexture.cpp
    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
    /*
    Copyright (C) 2003 Rice1964
     
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
    as published by the Free Software Foundation; either version 2
    of the License, or (at your option) any later version.
     
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
     
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
    */
     
    #include <stdlib.h>
     
    #include "Config.h"
    #include "Debugger.h"
    #include "OGLTexture.h"
    #include "TextureManager.h"
     
    COGLTexture::COGLTexture(uint32 dwWidth, uint32 dwHeight, TextureUsage usage) :
        CTexture(dwWidth,dwHeight,usage),
        m_glFmt(GL_RGBA)
    {
        // Fix me, if usage is AS_RENDER_TARGET, we need to create pbuffer instead of regular texture
     
        m_dwTextureFmt = TEXTURE_FMT_A8R8G8B8;  // Always use 32bit to load texture
        glGenTextures( 1, &m_dwTextureName );
     
        // Make the width and height be the power of 2
        uint32 w;
        for (w = 1; w < dwWidth; w <<= 1);
        m_dwCreatedTextureWidth = w;
        for (w = 1; w < dwHeight; w <<= 1);
        m_dwCreatedTextureHeight = w;
     
        if (dwWidth*dwHeight > 256*256)
            TRACE4("Large texture: (%d x %d), created as (%d x %d)", 
                dwWidth, dwHeight,m_dwCreatedTextureWidth,m_dwCreatedTextureHeight);
     
        m_fYScale = (float)m_dwCreatedTextureHeight/(float)m_dwHeight;
        m_fXScale = (float)m_dwCreatedTextureWidth/(float)m_dwWidth;
     
        m_pTexture = malloc(m_dwCreatedTextureWidth * m_dwCreatedTextureHeight * GetPixelSize());
     
        switch( options.textureQuality )
        {
        case TXT_QUALITY_DEFAULT:
            if( options.colorQuality == TEXTURE_FMT_A4R4G4B4 ) 
                m_glFmt = GL_RGBA4;
            break;
        case TXT_QUALITY_32BIT:
            break;
        case TXT_QUALITY_16BIT:
                m_glFmt = GL_RGBA4;
            break;
        };
        LOG_TEXTURE(TRACE2("New texture: (%d, %d)", dwWidth, dwHeight));
    }
     
    COGLTexture::~COGLTexture()
    {
        // Fix me, if usage is AS_RENDER_TARGET, we need to destroy the pbuffer
     
        glDeleteTextures(1, &m_dwTextureName );
        free(m_pTexture);
        m_pTexture = NULL;
        m_dwWidth = 0;
        m_dwHeight = 0;
    }
     
    bool COGLTexture::StartUpdate(DrawInfo *di)
    {
        if (m_pTexture == NULL)
            return false;
     
        di->dwHeight = (uint16)m_dwHeight;
        di->dwWidth = (uint16)m_dwWidth;
        di->dwCreatedHeight = m_dwCreatedTextureHeight;
        di->dwCreatedWidth = m_dwCreatedTextureWidth;
        di->lpSurface = m_pTexture;
        di->lPitch = GetPixelSize()*m_dwCreatedTextureWidth;
     
        return true;
    }
     
    void COGLTexture::EndUpdate(DrawInfo *di)
    {
        glBindTexture(GL_TEXTURE_2D, m_dwTextureName);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        // Copy the image data from main memory to video card texture memory
        glTexImage2D(GL_TEXTURE_2D, 0, m_glFmt, m_dwCreatedTextureWidth, m_dwCreatedTextureHeight, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, m_pTexture);
    }
     
     
    // Keep in mind that the real texture is not scaled to fix the created opengl texture yet.
    // when the image is need to be scaled, ScaleImageToSurface in CTexure will be called to 
    // scale the image automatically
    EDIT:
    Au passage, pour être un minimum valable, il faut que se soit spécifier dans la doc et surtout que la classe mère soit abstraite.
    J'ai pas bien compris. Pour que quoi soit valable? Ma modif? Ou le code original?

  4. #4
    Membre confirmé Avatar de Lavock
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    560
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 560
    Points : 633
    Points
    633
    Par défaut
    Article sur les fonctions virtuelles.

    Si justement, texture doit absolument être abstraite si on ne libère pas le pointeur dedans.

    Rien dans le code ne justifie une tel méthode. Au vue du code, je dirai que c'est pas génial. Le typedef struct {} nom est déprécié en C++... Et rien ne justifie non plus l'utilisation du couple malloc/free plutôt que new/delete...

    De manière général... C'est un code de niveau très moyen >< !

    [EDIT]Pour être claire, dans le code original, Texture DOIT être abstraite. C'est d'ailleurs le cas.
    The mark of the immature man is that he wants to die nobly for a cause, while the mark of the mature man is that he wants to live humbly for one.
    --Wilhelm Stekel

  5. #5
    Membre actif Avatar de Narann
    Inscrit en
    Juin 2007
    Messages
    140
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 140
    Points : 211
    Points
    211
    Par défaut
    En effet, c'est le code de mupen64plus. Il est assez vieux (je pense qu'un cleanage" est prévu quand la version windows sera stable).

    Je crois que j'ai compris pour l'abstraction.

    Mais ducoup ma question reste la même: Au vue du code, il vaut mieux mettre le free(m_pTexture) dans le destructeur de CTexture (qui est virtual) ou le laisser comme ça? (dans le destructeur de COGLTexture).

    Ou bien (et d'après tes dires j'ai l'impression que c'est le cas):

    Le code est trop crade pour le savoir...

    Merci pour tes réponse qu'il m'aide beaucoup!

    EDIT: En fait, le vrai problème c'est que j'ai un heap corrumption à la ligne free(m_pTexture). Et quand je le fait ma "manip" je ne l'ai plus... (Après, rien ne me dit qu'il n'y a pas de fuite mémoire et/ou que mon free() est bien effectif)...

  6. #6
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Salut,
    Le code que tu présentes ressemble à du mélange C/C++ et c'est pour ça qu'il comporte des comportements que nous qualifieront d'étranges pour être gentil.
    Pour répondre à ta question de base : oui, c'est une erreur. Si CTexture contient le pointeur, c'est qu'il s'engage à le gérer. Il devrait donc le libérer dans son destructeur et non pas laisser la tâche aux descendants.
    Ta corruption peut avoir d'autres origines :
    -> Ecrasement de la zone mémoire pointée ailleurs dans ton programme ;
    -> Multiple delete (je parie que la class CTexture ne gère ni la construction par copie, ni l'opérateur =) ;
    -> Adresse du pointeur invalide ;
    -> etc.
    Si tu peux :
    -> Transforme le pointeur en pointeur intelligent comme suggéré par Lavlock (cf F.A.Q. et tutoriels);
    -> Utilise un outil de type valgrind pour profiler ta gestion mémoire ;
    -> Armes toi de courage car au vu de ces quelques lignes, le travail va être ardue

  7. #7
    Membre confirmé Avatar de Lavock
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    560
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 560
    Points : 633
    Points
    633
    Par défaut
    En faite, dans le code actuel, la classe mère se décharge de la gestion du pointeur sur la classe fille. C'est "pas terrible". Si vraiment on as besoin d'une gestion intelligente, le mieux c'est de mettre en place des pointeurs intelligents.

    Ce que je disais, c'est qu'au vue du code que tu nous met, rien de justifie l'utilisation d'un tel gymnastique.

    Pour le problème de heap, le code montré ne me semble pas compromettant... Mais pourrait justement porté à confusion.

    Si ta version ne plante pas, c'est du à comment sont appelé les destructeurs lorsqu'il sont virtuel. En gros, si tu ne fais que ta "manip" sans enlever mp_texture = NULL, effectivement tu fais un free(NULL) (qui ne fait rien selon la norme).

    Question subsidiaire que j'aurais du poser plus tôt : qu'est-ce que LPRICETEXTURE ?

    [EDIT] Je parierai sur un double free(). OGLTexture a-t-elle une fille ?
    The mark of the immature man is that he wants to die nobly for a cause, while the mark of the mature man is that he wants to live humbly for one.
    --Wilhelm Stekel

  8. #8
    Membre actif Avatar de Narann
    Inscrit en
    Juin 2007
    Messages
    140
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 140
    Points : 211
    Points
    211
    Par défaut
    Merci pour vos réponses!
    Le code que tu présentes ressemble à du mélange C/C++ et c'est pour ça qu'il comporte des comportements que nous qualifieront d'étranges pour être gentil.
    En effet, je serai près à parier que mupen64 était codé en C et qu'il on restructuré le code pour le rendu OO et pouvoir mieux le maintenir).
    Merci pour les conseils 3DArchi, je vais voir tout ça de plus près.
    Si CTexture contient le pointeur, c'est qu'il s'engage à le gérer. Il devrait donc le libérer dans son destructeur et non pas laisser la tâche aux descendants.
    En faite, dans le code actuel, la classe mère se décharge de la gestion du pointeur sur la classe fille. C'est "pas terrible".
    C'est exactement ce que je me suis dis...
    Pour le problème de heap, le code montré ne me semble pas compromettant... Mais pourrait justement porté à confusion.
    Ce qui est bizarre c'est que je n'ai pas ça sous Mario Kart par exemple...
    Truc aussi "à la con", quand je transforme:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    m_pTexture = malloc(m_dwCreatedTextureWidth * m_dwCreatedTextureHeight * GetPixelSize());
    En
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    m_pTexture = malloc(m_dwCreatedTextureWidth * m_dwCreatedTextureHeight * GetPixelSize()*1000);
    Pour amplifier le problème, tout marche bien. Ma ram fait des bonds non stop mais pas de heap corrupt :/
    Je me demande si ce n'est pas ça:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
        // Make the width and height be the power of 2
        uint32 w;
        for (w = 1; w < dwWidth; w <<= 1);
        m_dwCreatedTextureWidth = w;
        for (w = 1; w < dwHeight; w <<= 1);
        m_dwCreatedTextureHeight = w;
     
        if (dwWidth*dwHeight > 256*256)
            TRACE4("Large texture: (%d x %d), created as (%d x %d)", 
                dwWidth, dwHeight,m_dwCreatedTextureWidth,m_dwCreatedTextureHeight);
     
        m_fYScale = (float)m_dwCreatedTextureHeight/(float)m_dwHeight;
        m_fXScale = (float)m_dwCreatedTextureWidth/(float)m_dwWidth;
    Qui fait foirer... (Je sais, c'est que de la supposition), je suis curieux et je vais essayer de debugger cette partie pour voir...
    Si ta version ne plante pas, c'est du à comment sont appelé les destructeurs lorsqu'il sont virtuel. En gros, si tu ne fais que ta "manip" sans enlever mp_texture = NULL, effectivement tu fais un free(NULL) (qui ne fait rien selon la norme).
    Bien joué! Je me sent bête de pas l'avoir vu moi même... J'essaierai aussi ça! Il y a des moyens de faire des warns sur la destruction de pointeur null? (Je sent que je dis une grosse bêtise...)
    Question subsidiaire que j'aurais du poser plus tôt : qu'est-ce que LPRICETEXTURE ?
    Si t'aime pas les typedef tu va pas être content :
    Dans typedef.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    typedef void* LPRICETEXTURE ;
    Je parierai sur un double free(). OGLTexture a-t-elle une fille ?
    J'y ai pensé aussi mais je n'ai rien trouvé. OGLTexture est le seul endroit ou on détruit m_pTexture.
    je parie que la class CTexture ne gère ni la construction par copie, ni l'opérateur = ;
    Ça c'est carrément possible mais vu la tête du code je n'arrive pas à trop savoir. Il faudrait que je sache me servir d'un debugger je pense pour ce genre de choses.

    Je vais chercher dans mon coin. Merci pour tout!

    A bientôt!


  9. #9
    Membre confirmé Avatar de Lavock
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    560
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 560
    Points : 633
    Points
    633
    Par défaut
    On peut simplement réécrire un free free-style, ou jouer avec les espace de noms.
    [edit]-----------------------------^
    Déjà, il faudrait vérifier que le malloc c'est bien passé. Ensuite, le remplacer par un new/delete... Mis à part si tu l'utilise dans une vielle fonction C (ce qui est possible si jamais c'est couplé openGL), mettre un type correct.

    Au vue des éléments, il y a for à parier qu'il y a quelque part un memcpy en dépassement.
    The mark of the immature man is that he wants to die nobly for a cause, while the mark of the mature man is that he wants to live humbly for one.
    --Wilhelm Stekel

  10. #10
    Membre actif Avatar de Narann
    Inscrit en
    Juin 2007
    Messages
    140
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 140
    Points : 211
    Points
    211
    Par défaut
    Citation Envoyé par Lavock Voir le message
    On peut simplement réécrire un free style
    Euh, un "free style"? J'ai pas compris...
    Citation Envoyé par Lavock Voir le message
    ou jouer avec les espace de noms.
    Merci j'y avais pas pensé. Ça va chambouler le code tout ça mais si ça me permet de mettre le doigt sur la fuite...
    Citation Envoyé par Lavock Voir le message
    Déjà, il faudrait vérifier que le malloc c'est bien passé.
    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
        // Make the width and height be the power of 2
        uint32 w;
        for (w = 1; w < dwWidth; w <<= 1);
        m_dwCreatedTextureWidth = w;
        for (w = 1; w < dwHeight; w <<= 1);
        m_dwCreatedTextureHeight = w;
     
        if (dwWidth*dwHeight > 256*256)
            TRACE4("Large texture: (%d x %d), created as (%d x %d)", 
                dwWidth, dwHeight,m_dwCreatedTextureWidth,m_dwCreatedTextureHeight);
     
        m_fYScale = (float)m_dwCreatedTextureHeight/(float)m_dwHeight;
        m_fXScale = (float)m_dwCreatedTextureWidth/(float)m_dwWidth;
     
        m_pTexture = malloc(m_dwCreatedTextureWidth * m_dwCreatedTextureHeight * GetPixelSize());
    Je pense aussi qu'il peut y avoir quelque chose ici. Mais ce qu'il faut savoir c'est qu'avant de planter, il appel tout ça (malloc et free) des centaines de fois. Et aussi que (pour l'instant), je n'ai qu'un seul rom qui me fait ça (Goldeneye). Je vais essayer de "tracker" la taille du malloc.
    Citation Envoyé par Lavock Voir le message
    Ensuite, le remplacer par un new/delete...
    J'aimerai je tenterai ça aussi...
    Citation Envoyé par Lavock Voir le message
    Mis à part si tu l'utilise dans une vielle fonction C (ce qui est possible si jamais c'est couplé openGL), mettre un type correct.
    Ben tu a vu le code. C'est "bizarre" disons. C'est le plugin d'affichage (Rice) de mupen64plus...
    Son écriture date un peu (à l'époque de mupen64) et, aux vues du codes. Il a du être écrit en C d'origine puis "importé" en C++ (lors du passage à mupen64plus)... C'est clair qu'il mériterai une réécriture "correct"...
    Citation Envoyé par Lavock Voir le message
    Au vue des éléments, il y a for à parier qu'il y a quelque part part un memcpy en dépassement.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    memcpy((uint8*)g_ucTempBuffer, (uint8*)(di.lpSurface), m_dwHeight*m_dwCreatedTextureWidth*4);
    memcpy((uint8*)g_ucTempBuffer, (uint8*)(di.lpSurface), m_dwHeight*m_dwCreatedTextureWidth*2);
    Intéressant, il y en a d'autres, je vais chercher un peu...

    Merci de ta réponse

  11. #11
    Membre confirmé Avatar de Lavock
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    560
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 560
    Points : 633
    Points
    633
    Par défaut
    J'ai edit mon message. J'avais oublié un "free"...
    The mark of the immature man is that he wants to die nobly for a cause, while the mark of the mature man is that he wants to live humbly for one.
    --Wilhelm Stekel

  12. #12
    Membre actif Avatar de Narann
    Inscrit en
    Juin 2007
    Messages
    140
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 140
    Points : 211
    Points
    211
    Par défaut
    A ok! Je comprend mieux!

    Après tests il semble que le destructeur parent (CTexture) ne soit pas appelé après le destructeur de OGLTexture. Donc en gros, déplacer mon free+NULL du destructeur d'OGLTexture au destructeur CTexture revient au final à faire une fuite de mémoire...

    D'après le dev, quelque chose d'autre essai d'accéder et/ou d'écrire sur la texture après qu'elle eu été libéré.
    There is a GetTexture() method which returns the pointer to m_pTexture. Some object is getting (and possibly storing) this pointer and then still using it after the original texture is destroyed.
    Je vais essayer de trouver ce nouveau pointeur... qui continue à faire des choses alors qu'il n'a pas le droit.

  13. #13
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Citation Envoyé par Narann Voir le message
    Après tests il semble que le destructeur parent (CTexture) ne soit pas appelé après le destructeur de OGLTexture.
    Ca c'est un bug. Fais tu un delete ou un free sur OGLTexture ? Car un delete DOIT appeler les destructeurs parents. C'est le langage qui te le garanti. La seule exception : type dynamique != type statique et destructeur non virtuel auquel cas le comportement est indéterminé.

  14. #14
    Membre actif Avatar de Narann
    Inscrit en
    Juin 2007
    Messages
    140
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 140
    Points : 211
    Points
    211
    Par défaut
    Citation Envoyé par 3DArchi Voir le message
    Ca c'est un bug. Fais tu un delete ou un free sur OGLTexture ? Car un delete DOIT appeler les destructeurs parents. C'est le langage qui te le garanti. La seule exception : type dynamique != type statique et destructeur non virtuel auquel cas le comportement est indéterminé.
    Je vais passer pour un idiot mais: "Après retest, Il semble que le destructeur de CTexture soit appelé."

    Ça me rassure en fait.

    A propos, je n'ai pas écrit le message de heap:

    HEAP CORRUPTION DETECTED: after Normal block (#11639) at 0x0790FF10.
    CRT detected that the application wrote to memory after end of heap buffer.
    Comment un free peut "écrire dans la mémoire après la fin du la mémoire alloué"?

  15. #15
    Membre confirmé Avatar de Lavock
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    560
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 560
    Points : 633
    Points
    633
    Par défaut
    Parce que tu fais un memcpy plus long que ton allocation par exemple.
    Si jamais par hasard, tu ne tape pas de page fault majeur (illégal adresse, apellé aussi segfault), tu aura une zone qui fera croire qu'elle est plus grande que ce qu'elle est. Et lorsque tu va chercher à désalouer, il va se dire : "mais zut, ça je peux pas le désalouer", et te crache une erreur.

    Et il ne te dit pas que le free écrit, il te dit "application wrote". En réalité le free aussi écrit, mais c'est pas ce qui le gêne vraiment.
    The mark of the immature man is that he wants to die nobly for a cause, while the mark of the mature man is that he wants to live humbly for one.
    --Wilhelm Stekel

  16. #16
    Membre actif Avatar de Narann
    Inscrit en
    Juin 2007
    Messages
    140
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 140
    Points : 211
    Points
    211
    Par défaut
    Ok merci, donc si je comprend bien:
    free essai de désalouer plus de mémoire qu'il n'y en a réellement?

    Donc, entre le m_pTexture = malloc(SIZE) et le free(m_pTexture), il y a un changement de la taille de m_pTexture?

  17. #17
    Membre confirmé Avatar de Lavock
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    560
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 560
    Points : 633
    Points
    633
    Par défaut
    Un "changement" implicite oui.
    The mark of the immature man is that he wants to die nobly for a cause, while the mark of the mature man is that he wants to live humbly for one.
    --Wilhelm Stekel

  18. #18
    Membre actif Avatar de Narann
    Inscrit en
    Juin 2007
    Messages
    140
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 140
    Points : 211
    Points
    211
    Par défaut
    'tin, vu que:
    - Ce n'est pas mon code
    - Je ne suis pas un développeur
    - C'est mal écrit


    Je vais galérer...

    A part avec mes yeux il n'y a aucune méthode pour déterminer quand un "pointeur change de taille"?

    Ou mieu, connaitre la taille d'un pointeur.

    Comme ça je stock dans l'objet la taille de se pointeur à l'allocation, je la vérifie avant le free et je break. Puis je remonte jusqu'à la source du changement.

    Je dis peut être une grosse ânerie cela dit...

  19. #19
    Membre confirmé Avatar de Lavock
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    560
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 560
    Points : 633
    Points
    633
    Par défaut
    Héhé non, aucun moyen de connaître quand est-ce que ton tableau "s'agrandit"...

    Le mieux, c'est de faire plutôt qu'un pointeur, une classe ou tu surcharge l'op []. Ainsi, tu pourra peut-être, je dis bien peut-être, voir le dépassement en écriture >< !
    Sinon, ben il te reste plus qu'a foutre des watch comme il faut sur ton tableau en espérant que ça te révèle là ou ça fais n'importe quoi....
    The mark of the immature man is that he wants to die nobly for a cause, while the mark of the mature man is that he wants to live humbly for one.
    --Wilhelm Stekel

  20. #20
    Membre actif Avatar de Narann
    Inscrit en
    Juin 2007
    Messages
    140
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 140
    Points : 211
    Points
    211
    Par défaut
    Hello! J'ai trouvé (a coups de debug et de printf!)

    J'ai remarqué en matant mes variables que ce ne sont que les textures 1x1 qui plante. Mais pas toute!

    Comme je l'ai dis, il y a une petite opération avant le malloc pour transformer la taille de la texture en puissance de 2.

    Je me suis dis "a tout les coups", dans le reste du code, il doit y avoir une boucle qui traite les pixel en considérant sa taille minimal comme 2x2. En effet, 1 n'est pas une puissance de deux mais est supporté par les cartes graphiques! Et il y a peut être eu une confusion quelque part.

    J'ai donc directement cherché au niveau des conversion et en effet.

    Le convertisseur ConvertCI4_RGBA16 de ConvertImage.cpp à une joli boucle comme ça (pDst est un pointeur vers le premier pixel de la texture a convertir):
    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
     
    for (uint32 x = 0; x < tinfo.WidthToLoad; x+=2)
                {
                    uint8 b = pSrc[dwByteOffset ^ nFiddle];
     
                    uint8 bhi = (b&0xf0)>>4;
                    uint8 blo = (b&0x0f);
     
                    //pDst[0] = Convert555ToRGBA(pPal[bhi^1]); //when I comment this
                    //pDst[1] = Convert555ToRGBA(pPal[blo^1]); //and this, it not crash
     
                    if( bIgnoreAlpha )
                    {
                        pDst[0] |= 0xFF000000;
                        pDst[1] |= 0xFF000000;
                    }
     
                    pDst+=2;
     
                    dwByteOffset++;
                }
    Le convertisseur fait deux opération successives (Convert555ToRGBA) et avance dans le pointeur de "deux" (x+=2). Le seul prob, c'est que quand tinfo.WidthToLoad = 1, il écrit sa seconde ligne: pDst[1] = Convert555ToRGBA(pPal[blo^1]), "dans le vide". Ce qui me fait que je me retrouve avec un taille a désalouer plus grand que ce qu'avait alloué mon malloc...

    A partir de la, deux solution. Soit, dans la partir des puissances de deux:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    If (1x1 map)
     2x2 maps;
    Et tout marche impec!
    Soit (peut être plus "propre") directement dans la convertion. Un peu plus crade à écrire mais surement plus clean en terme de fonctionnement (j'en sais rien en fait) mais il y a quand même une bonne dizaine de convertisseurs à faire dans ce cas là.

    J'en ai notifié le dev principal du projet, je verrai ce qu'il compte faire.

    La ou je trouve ça très surprenant (et vous allez peut être pouvoir m'aider), c'est que je n'ai pas ce heap corrumption sous linux. Je sais que la gestion de la mémoire entre Linux et Win 7 est très différente. N'hésitez pas si vous avez des idées.

    Dans tout les cas je vous remercie bcp de toute votre aide!

    A bientôt!

    EDIT: Dernier point, je viens de regarder les version 0.5 de mupen64 et le code était en full C, ce qui explique les malloc à tour de bras. C'est clair que ce code mérite un bon gros clean!

Discussions similaires

  1. Réponses: 8
    Dernier message: 05/04/2011, 08h06
  2. Réponses: 6
    Dernier message: 13/11/2009, 16h06
  3. Réponses: 3
    Dernier message: 26/02/2007, 10h14
  4. Réponses: 4
    Dernier message: 16/05/2006, 23h15
  5. Réponses: 11
    Dernier message: 06/12/2005, 08h23

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