Re: Question de cc

Page principale

Répondre à ce message
Auteur: David Beniamine
Date:  
À: guilde
Sujet: Re: Question de cc
On Fri, Apr 08, 2016 at 08:23:03PM +0200, Patrick Dupre wrote:
> Est-ce qu'il y a un probleme avec ce code ?
> Si je commente char pot, ou que je reduis la dimension des tableaux,
> ca passe. Sinon, je recupere un segmentation fault!
>
>
> #include <stdio.h>
> #include <math.h>
> #include <stdlib.h>
>
> #define MAX_LEV 64
> #define MAX_NB 16384
>
> void main () {
>
>     double x [MAX_NB], y [MAX_LEV] [MAX_NB] ;
>     double z [MAX_NB] ;

>
>     char pot [] = "12" ;

>
>     }

>
>
> ===========================================================================
>  Patrick DUPRÉ                                 | | email: pdupre@???
>  Laboratoire de Physico-Chimie de l'Atmosphère | |
>  Université du Littoral-Côte d'Opale           | |
>  Tel.  (33)-(0)3 28 23 76 12                   | | Fax: 03 28 65 82 44
>  189A, avenue Maurice Schumann                 | | 59140 Dunkerque, France
> ===========================================================================

>


Bonsoir,

Le "bug" est asse subtile et peut être résolu de plusieurs manières:
Tu déclare plusieurs énormes tableaux statiquement dans une fonction,
ces données sont donc allouée dans la pile qui a une taille limite sur
mon pc (et probablement sur le tiens aussi) 8388608 octets, or ton code
alloue: 8650752octets.
Tu peux voir ça avec ce printf par exemple:

    printf("%lu\n", sizeof(double)*(MAX_NB*(2+MAX_LEV)));


Il y a trois façon de régler ce soucis:

+ The good: Faire des allocations dynamiques a l'aide de malloc, ça
            mettera les données dans le tas, une zone mémoire prévue
            pour ça tout en évitant de faire des déclaration globale ce
            qui n'est jamais une bonne idée.
+ The bad:  Déclarer les variables en globale (avant le main) pour que
            les allocations statique ne soient pas dans la pile. C'est
            la modification de code la plus simple mais sur un programme
            plus gros ça veux dire que les variables sont accessible et
            donc modifiable partout ce qui rends le debug difficile...
+ The ugly: Augmenter la taille de la pile.


Ton code réécrit avec des mallocs:

#include <stdio.h>
#include <math.h>
#include <stdlib.h>

#define MAX_LEV 64
#define MAX_NB 16384

int main () {

    int i;
    double *x=(double *)malloc(sizeof(double)*MAX_NB);
    if(!x)
        return 1;
    double **y=(double **)malloc(sizeof(double *)*MAX_LEV);
    if(!y)
        return 1;
    for(i=0;i<MAX_LEV;++i){
        y[i] = (double *)malloc(sizeof(double)*MAX_NB);
        if(!y[i])
            return 1;
    }
    double *z=(double *)malloc(sizeof(double)*MAX_NB);


    char pot [] = "12" ;


    // DO stuff


    // Free everything
    free(x);
    free(z);
    for(i=0;i<MAX_LEV;++i)
        free(y[i]);
    free(y);
    return 0;


    }


Quelques pointeurs:
Malloc:
https://en.wikipedia.org/wiki/C_dynamic_memory_allocation
Portées des variables et différence tas/pile:
http://stackoverflow.com/questions/79923/what-and-where-are-the-stack-and-heap/80113
Stack size:
http://stackoverflow.com/questions/2279052/increase-stack-size-in-linux-with-setrlimit
http://www.ehow.com/how_8359635_increase-stack-size-linux.html