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 => segFault


Sujet :

C++

  1. #1
    Membre confirm�
    Profil pro
    Inscrit en
    F�vrier 2006
    Messages
    63
    D�tails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : F�vrier 2006
    Messages : 63
    Par d�faut Malloc => segFault
    Bonjour,

    J'ai �crit un programme (calculant des indices de sensibilit� pour mon stage de 2A) qui n�cessite d'initialiser tout plein de zones m�moire (pour aller plus vite):

    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
     
     
    int i,ip,ipp;
    long j,k,l,aux,tmpl;
    long *casesY,*p,*estimationsX,*estimationsY;
    long **casesX,**estimationsXX,**estimationsXY=0;
    long ***estimationsXXY;
     
    double sum,H0=0,pasX,tmp;
    double *infX,*infY,*supX,*supY,*pasY,*mS1=0,*minS1=0,*maxS1=0,*sigS1=0;
    double **mS2=0,**minS2=0,**maxS2=0,**sigS2=0,**X,**Y,**HK=0;
    double ***HK2=0;
     
    /* initialisation des tableaux contenant les indices */
    if (Si) {
        HK=(double**)malloc(dim_x*sizeof(double*));
        for (i=dim_x-1; i>=0; i--) {
            HK[i]=(double*)malloc(R*sizeof(double));
            for (ip=R-1; ip>=0; ip--) HK[i][ip]=0;
        }
        mS1=(double*)malloc(dim_x*sizeof(double));
        minS1=(double*)malloc(dim_x*sizeof(double));
        maxS1=(double*)malloc(dim_x*sizeof(double));
        sigS1=(double*)malloc(dim_x*sizeof(double));
    } 
    if (Sij) {
        HK2=(double***)malloc(dim_x*sizeof(double**));
        for (i=dim_x-1; i>=0; i--) {
            HK2[i]=(double**)malloc(dim_x*sizeof(double*));
            for (ip=dim_x-1; ip>=0; ip--) {
                HK2[i][ip]=(double*)malloc(R*sizeof(double));
                for (ipp=R-1; ipp>=0; ipp--) HK2[i][ip][ipp]=0;
            }
        }
        mS2=(double**)malloc(dim_x*sizeof(double*));
        for (i=dim_x-1; i>=0; i--) mS2[i]=(double*)malloc(dim_x*sizeof(double));
        minS2=(double**)malloc(dim_x*sizeof(double*));
        for (i=dim_x-1; i>=0; i--) minS2[i]=(double*)malloc(dim_x*sizeof(double));
        maxS2=(double**)malloc(dim_x*sizeof(double*));
        for (i=dim_x-1; i>=0; i--) maxS2[i]=(double*)malloc(dim_x*sizeof(double));
        sigS2=(double**)malloc(dim_x*sizeof(double*));
        for (i=dim_x-1; i>=0; i--) sigS2[i]=(double*)malloc(dim_x*sizeof(double));
    } 
     
    /* autres initialisations */
    aux=puiss(n+1,dim_y); 
    p=(long*)malloc(dim_y*sizeof(long));
    for (i=dim_y; i>=0; i--) p[i]=puiss(n+1,i);
    estimationsY=(long*)malloc((aux+1)*sizeof(long)); 
    X=(double**)malloc(dim_x*sizeof(double*));
    for (i=dim_x-1; i>=0; i--) X[i]=(double*)malloc(S*sizeof(double)); 
    infX=(double*)malloc(dim_x*sizeof(double));
    supX=(double*)malloc(dim_x*sizeof(double));
    infY=(double*)malloc(dim_y*sizeof(double));
    supY=(double*)malloc(dim_y*sizeof(double));
    pasY=(double*)malloc(dim_y*sizeof(double));
    casesY=(long*)malloc(S*sizeof(long));
    casesX=(long**)malloc(dim_x*sizeof(long*));
    for (i=dim_x-1; i>=0; i--) casesX[i]=(long*)malloc(S*sizeof(long));
    estimationsX=(long*)malloc((n+1)*sizeof(long));
    if (Si) {
       estimationsXY=(long**)malloc((n+1)*sizeof(long*));
       for (j=n; j>=0; j--)
           estimationsXY[j]=(long*)malloc((aux+1)*sizeof(long));
    }
    estimationsXX=(long**)malloc((n+1)*sizeof(long*));
    estimationsXXY=(long***)malloc((n+1)*sizeof(long**));
    for (j=n; j>=0; j--) {
        estimationsXX[j]=(long*)malloc((n+1)*sizeof(long));
        estimationsXXY[j]=(long**)malloc((n+1)*sizeof(long*));
        for (k=n; k>=0; k--) 
            estimationsXXY[j][k]=(long*)malloc((aux+1)*sizeof(long));
    }
    Contrairement aux apparences c'est bien du C++ ^^
    En revanche:

    - Ca marche avec dev-cpp sous windows
    - Ca plante syst�matiquement avant la fin des allocations avec g++ sous Unix; message d'erreur:

    (gdb) run e Parametres/paramE_hs.dat hs 1000 100
    Starting program: /home/iooss/benjamin/main e Parametres/paramE_hs.dat hs 1000 100

    Program received signal SIGSEGV, Segmentation fault.
    0x42074675 in _int_malloc () from /lib/tls/libc.so.6
    (gdb) bt
    #0 0x42074675 in _int_malloc () from /lib/tls/libc.so.6
    #1 0x4207378d in malloc () from /lib/tls/libc.so.6
    #2 0x0804ebcb in entrop ()
    #3 0x0804adff in main ()
    #4 0x42015704 in __libc_start_main () from /lib/tls/libc.so.6

    Faut-il que je transforme tous mes "malloc" en "new" ?
    Ce qui m'emb�te c'est que le code suivant fonctionne sous Unix avec g++:

    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
     
     
    int i,ip,ipp,j;
    long k;
    double V0=0,my=0;
    double *Y,*Yp,*mS1=0,*mSt=0,*minS1=0,*minSt=0,*maxS1=0,*maxSt=0,*sigS1=0,*sigSt=0;
    double **mS2=0,**minS2=0,**maxS2=0,**sigS2=0,**X1,**X2,**sav,**S1=0,**St=0;
    double ***S2=0;
     
    /* initialisation des tableaux contenant les indices */
    if (Si) {
        S1=(double**)malloc(dim_x*sizeof(double*));
        for (i=dim_x-1; i>=0; i--) {
            S1[i]=(double*)malloc(R*sizeof(double)); 
            for (ip=R-1; ip>=0; ip--) S1[i][ip]=0;
        }
        mS1=(double*)malloc(dim_x*sizeof(double));
        minS1=(double*)malloc(dim_x*sizeof(double));
        maxS1=(double*)malloc(dim_x*sizeof(double));
        sigS1=(double*)malloc(dim_x*sizeof(double));
    }
    if (Sij) {
        S2=(double***)malloc(dim_x*sizeof(double**));
        for (i=dim_x-1; i>=0; i--) {
            S2[i]=(double**)malloc(dim_x*sizeof(double*));
            for (ip=dim_x-1; ip>=0; ip--) {
                S2[i][ip]=(double*)malloc(R*sizeof(double));
                for (ipp=R-1; ipp>=0; ipp--) S2[i][ip][ipp]=0;
            }
        }
        mS2=(double**)malloc(dim_x*sizeof(double*));
        for (i=dim_x-1; i>=0; i--) mS2[i]=(double*)malloc(dim_x*sizeof(double));
        minS2=(double**)malloc(dim_x*sizeof(double*));
        for (i=dim_x-1; i>=0; i--) minS2[i]=(double*)malloc(dim_x*sizeof(double));
        maxS2=(double**)malloc(dim_x*sizeof(double*));
        for (i=dim_x-1; i>=0; i--) maxS2[i]=(double*)malloc(dim_x*sizeof(double));
        sigS2=(double**)malloc(dim_x*sizeof(double*));
        for (i=dim_x-1; i>=0; i--) sigS2[i]=(double*)malloc(dim_x*sizeof(double));
    } 
    if (Sti) {
        St=(double**)malloc(dim_x*sizeof(double*));
        for (i=dim_x-1; i>=0; i--) {
            St[i]=(double*)malloc(R*sizeof(double));
            for (ip=R-1; ip>=0; ip--) St[i][ip]=0;
        }
        mSt=(double*)malloc(dim_x*sizeof(double));
        minSt=(double*)malloc(dim_x*sizeof(double));
        maxSt=(double*)malloc(dim_x*sizeof(double));
        sigSt=(double*)malloc(dim_x*sizeof(double));
    }
     
    /* autres initialisations */
    X1=(double**)malloc(dim_x*sizeof(double*));
    for (i=dim_x-1; i>=0; i--) X1[i]=(double*)malloc(S*sizeof(double));
    X2=(double**)malloc(dim_x*sizeof(double*));
    for (i=dim_x-1; i>=0; i--) X2[i]=(double*)malloc(S*sizeof(double));
    sav=(double**)malloc(dim_x*sizeof(double*));
    for (i=dim_x-1; i>=0; i--) sav[i]=(double*)malloc(S*sizeof(double));
    alors que les allocations n�cessaires sont plus grandes que dans le cas pr�c�dent (n de l'ordre de 100, S peut atteindre 500000, 1000000..etc).

    Je n'y comprend rien (comme d'habitude :-/)

    Merci d'avance,
    Benjamin.

  2. #2
    Membre chevronn�
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    464
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 464
    Par d�faut
    ton code n'est pas s�curis� du tout: tu �cris dans des zones m�moires pour lesquelles le succ�s d'allocation n'a pas �t� v�rifi�.

    pas �tonnant dans ces conditions qu'il y ait des crashes plus ou moins al�atoires...

  3. #3
    Invit�
    Invit�(e)
    Par d�faut
    je ne me suis pas pench� sur le code plus que ca.
    j'ai une question pourtant :

    si c'est bel et bien du C++, pourquoi ne pas utiliser new pour allouer ta m�moire ?
    et puisque tu as l'air de g�rer plusieurs tableaux, pourquoi ne pas se servir dans les conteneurs STL ?? (std::vector par ex)

  4. #4
    Membre chevronn�
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    464
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 464
    Par d�faut
    Citation Envoy� par toxcct
    si c'est bel et bien du C++, pourquoi ne pas utiliser new pour allouer ta m�moire ?
    Si je peux me permettre, �a ne changerait rien : new, au m�me titre que malloc peut �chouer. D'ailleurs la plupart des impl�mentations de new utilisent malloc pour allouer la m�moire des objets instanci�s...

  5. #5
    Expert �minent
    Avatar de M�dinoc
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 41
    Localisation : France

    Informations professionnelles :
    Activit� : D�veloppeur informatique
    Secteur : High Tech - �diteur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par d�faut
    Et pire, le new standard lance une exception en cas d'�chec. Dans le cas d'une allocation de masse, c'est pas le mieux...

    En tout cas, pour plus de s�curit�, je pense que tu peux r�duire le nombre d'allocations � une par dimension pour chaque tableau, ce qui serait peut-�tre un peu moins fouillis (et r�clamerait moins de tests de r�ussite ou �chec).
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parl� avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  6. #6
    Membre confirm�
    Profil pro
    Inscrit en
    F�vrier 2006
    Messages
    63
    D�tails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : F�vrier 2006
    Messages : 63
    Par d�faut
    Les conteneurs de la STL sont beaucoup trop lents ;o) (en tout cas c'est ce que j'ai constat� en programmant un jeu de dame cette ann�e).

    Ca m'inqui�te quand m�me que ces allocations �chouent: m�me pour S=10 et n=10 �a plante, alors que dans ce cas il faut juste quelques centaines d'octets, au pire quelques milliers :-/

    Je suis d'accord que le code n'est pas s�curis� du tout, mais si on refuse de m'allouer 100 octets parce qu'il n'y a plus de m�moire, hein..

  7. #7
    Membre confirm�
    Profil pro
    Inscrit en
    F�vrier 2006
    Messages
    63
    D�tails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : F�vrier 2006
    Messages : 63
    Par d�faut
    Citation Envoy� par M�dinoc
    En tout cas, pour plus de s�curit�, je pense que tu peux r�duire le nombre d'allocations � une par dimension pour chaque tableau, ce qui serait peut-�tre un peu moins fouillis (et r�clamerait moins de tests de r�ussite ou �chec).
    Bonne id�e, je vais essayer ^^

  8. #8
    Membre exp�riment�
    Avatar de superspag
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    153
    D�tails du profil
    Informations personnelles :
    �ge : 45
    Localisation : France, Is�re (Rh�ne Alpes)

    Informations forums :
    Inscription : Janvier 2006
    Messages : 153
    Par d�faut
    Les conteneurs de la STL sont beaucoup trop lents ;o) (en tout cas c'est ce que j'ai constat� en programmant un jeu de dame cette ann�e).
    C'est surtout vraie en Debug mais en Release il n'y a pas de difference ou tr�s peu... Le plus dur je pense, c'est de bien choisir son conteneur. Selon l'utilisation, certains conteneurs sont pr�f�rables � d'autres...

  9. #9
    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
    Ce n'est pas parce qu'un code semble fonctionner qu'il est correct. Il est vite fait de faire des buffers overflow. Quand on commence � avoir des **, c'est une de trop -- si ce n'est pas deux. Alors ***, c'est des bugs � coup s�r.

    Citation Envoy� par M�dinoc
    Et pire, le new standard lance une exception en cas d'�chec. Dans le cas d'une allocation de masse, c'est pas le mieux...
    Au moins inutile de mettre 150 if pour tester tous les echecs possibles. Une exception, et on avorte. Apr�s, la r�cup�ration de la m�moire n'est pas plus compliqu�e (ni plus simple). Inutile aussi de sp�cifier des choses que le compilo connait d�j� => les tailles des types primitifs � alouer.

    En tout cas, pour plus de s�curit�, je pense que tu peux r�duire le nombre d'allocations � une par dimension pour chaque tableau, ce qui serait peut-�tre un peu moins fouillis (et r�clamerait moins de tests de r�ussite ou �chec).
    Ou utiliser directement un truc efficace qui est fait pour g�rer plusieurs dimensions => boost.multi_array, std::vector<std::vector<...>>.

    Les conteneurs de la STL sont beaucoup trop lents ;o) (en tout cas c'est ce que j'ai constat� en programmant un jeu de dame cette ann�e).
    C'est s�r que si tu les copies � chaque passage de param�tres ...
    google => "n1666 filtetype:pdf"
    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...

  10. #10
    Membre confirm�
    Profil pro
    Inscrit en
    F�vrier 2006
    Messages
    63
    D�tails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : F�vrier 2006
    Messages : 63
    Par d�faut
    Citation Envoy� par Luc Hermitte
    C'est s�r que si tu les copies � chaque passage de param�tres ...
    google => "n1666 filtetype:pdf"
    Non non j'avais fait attention � �a, mais dans le cas du prog jeu de dames je devais repr�senter des coups par des suites de coordonn�es; au lieu de faire des push_back sur un vecteur �a a gagn� pas mal de temps d'utiliser un simple pointeur initialis� avec une taille assez grande.

    Merci � tout le monde, je devrais m'en sortir avec tous ces conseils ^^

  11. #11
    Membre exp�riment�
    Avatar de superspag
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    153
    D�tails du profil
    Informations personnelles :
    �ge : 45
    Localisation : France, Is�re (Rh�ne Alpes)

    Informations forums :
    Inscription : Janvier 2006
    Messages : 153
    Par d�faut
    au lieu de faire des push_back sur un vecteur �a a gagn� pas mal de temps d'utiliser un simple pointeur initialis� avec une taille assez grande
    Il faut faire attention aux push_back qui peuvent provoquer une r�allocation de tout le vector !
    Le vector doit connaitre sa capacit� max pour etre otpimal.
    Tu peux utiliser la fonction setCapacity et ainsi utiliser des push_back tranquillement jusqu'a la taille max. Sinon il faut allouer le vector directement � la taille souhait� et y acceder via l'operateur [].

    Exemple d'allocation d'une matrice de taille N :

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
     
    const unsigned short N = 3000;
    std::vector< std::vector<double> > mat(N, std::vector<double>(N)); // Allocation d'une matrice NxN

  12. #12
    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
    - std::vector<>::reserve() augmente la capacit� ; il n'y a aucune construction/initialisation
    - std::vector<>::resize() augmente la taille "officielle" (peut faire un appel � r�serve si la capacit� est insuffisante), et construit les nouveaux �l�ments � une valeur par d�faut pouvant �tre explicit�e
    - Le constructor prenant une taille en param�tre r�alise un appel � resize (dans le principe)
    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. Segfault sur un malloc[Contourn�]
    Par Alfrodull dans le forum D�buter
    R�ponses: 3
    Dernier message: 08/01/2012, 17h27
  2. Segfault �trange sur un malloc
    Par |PaRa-BoL dans le forum C
    R�ponses: 38
    Dernier message: 17/01/2007, 14h57
  3. Pb : malloc qui marche une fois sur deux .... ?
    Par guillaume_pfr dans le forum C
    R�ponses: 14
    Dernier message: 21/07/2003, 09h52
  4. Erreur de sgmentation avec malloc
    Par simonm dans le forum C
    R�ponses: 5
    Dernier message: 27/02/2003, 08h29
  5. R�ponses: 4
    Dernier message: 03/12/2002, 16h47

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