Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 11/06/2010, à 18:14

superZozo

[Résolu] langage C, dépassement de tas sur gros tableaux...

Bonjour,

J'ai affaire visiblement à un dépassement de tas (heap overflow) sur un de mes programmes :
j'ai une erreur de segmentation sur la première instruction d'une fonction même si c'est un bête printf("ok!\n") sad

Ce problème est apparu depuis que j'ai augmenté la taille de certains tableaux (de structures). la taille est d'environ 1 000 000.

J'ai beau le tourner dans tous les sens avec des mallocs, je ne parviens pas à l'empêcher.

Quelqu'un connait'il un moyen, à part en diminuant la taille du tableau ou en ecrivant sur le dur

Par avance merci

Dernière modification par superZozo (Le 12/06/2010, à 10:59)

Hors ligne

#2 Le 11/06/2010, à 18:18

helly

Re : [Résolu] langage C, dépassement de tas sur gros tableaux...

Donne nous le code d'abord !

Dernière modification par helly (Le 11/06/2010, à 18:25)


Archlinux-wmii-dwb.
Un problème résolu ? Faites le savoir en mettant [résolu] à côté du titre de votre topic.
Un problème non résolu ? Faites le savoir en insultant ceux qui cherchent à vous aider.
Un site bleu super remasterised©, un wiki cherchant des volontaires pour traduire un site.

Hors ligne

#3 Le 11/06/2010, à 18:42

grim7reaper

Re : [Résolu] langage C, dépassement de tas sur gros tableaux...

helly a écrit :

Donne nous le code d'abord !

+42
In code we trust.

On n'as pas de boule de cristal donc sans code c'est quasi impossible de t'aider (sauf sur des erreurs triviales).

La taille du tableau n'est pas le problème, j'en ai déjà manipulé des plus gros. La vérité est ailleurs tongue.

Hors ligne

#4 Le 11/06/2010, à 18:43

superZozo

Re : [Résolu] langage C, dépassement de tas sur gros tableaux...

Ben, c'est un peu long j'ai 20 fichiers sources et sans doute environ 3000 lignes de code.
C'est un programme qui marchait mais que je veux modifier pour qu'il prenne en compte plus de données. tongue

Mais en gros j'ai des tableaux qui sont passés d'environ 100 000 à 900 000 et là ça plante sur un printf("ok! ");

Hors ligne

#5 Le 11/06/2010, à 18:46

grim7reaper

Re : [Résolu] langage C, dépassement de tas sur gros tableaux...

Et bien alors isole la portion de code qui pose problème et poste un code minimal qui reproduit l'erreur. Ainsi on pourra bosser dessus.
C'est aisé quand le programme est convenablement découpé en unités relativement indépendantes.

Hors ligne

#6 Le 11/06/2010, à 19:42

superZozo

Re : [Résolu] langage C, dépassement de tas sur gros tableaux...

Bon, ce n'est pas du tout facile "d'isoler" le code. Comme je l'ai dit, on peut déclencher une erreur de segmentation sur n'importe quoi même un simple printf(""); ce qui indique que c'est le tas (heap) et non la pile (stack) qui est écrasé.

Pour les sceptiques voici un exemple :
(jouer avec GROSCHIFFRE car le comportement dépend du PC...)

main.h

typedef struct //objet à afficher
{
    float x;//coordonnees
    float y;
    float z;
    float taille;//taille

    void* ref;//pointeur vers un objet quelconque...
}
objet;

void allocations(void);
void test(void);

main.c

//includes
#include <stdlib.h>
#include <stdio.h>

#include "main.h"

#define GROSCHIFFRE 3000000

objet** GROSTABLEAU;

int main(int argc, char ** argv)
{
    printf("démarrage\n");


    allocations();//allocations mémoire

    test();

    printf("sortie.\n");//fin
    return EXIT_SUCCESS;
}

void allocations(void)
{
    int i,j;
    int n =100;
    GROSTABLEAU = malloc(n*sizeof(objet*));

    for(j=0;j<n;j++)
    {
        GROSTABLEAU[j] = malloc(GROSCHIFFRE*sizeof(objet));
        printf("%d \n",j);
        for(i=0;i<GROSCHIFFRE;i++)
        {
            GROSTABLEAU[j][i].x = 0.1;
            GROSTABLEAU[j][i].y = 0.1;
            GROSTABLEAU[j][i].z = 0.1;
            GROSTABLEAU[j][i].taille = 100.;
            GROSTABLEAU[j][i].ref = NULL;
        }
    }
}
void test(void)
{
    printf("convaincu ?\n");
}

Hors ligne

#7 Le 11/06/2010, à 20:11

grim7reaper

Re : [Résolu] langage C, dépassement de tas sur gros tableaux...

superZozo a écrit :

Bon, ce n'est pas du tout facile "d'isoler" le code. Comme je l'ai dit, on peut déclencher une erreur de segmentation sur n'importe quoi même un simple printf(""); ce qui indique que c'est le tas (heap) et non la pile (stack) qui est écrasé.

Heu non, il n'y a absolument aucune corrélation entre un signal SIGSEGV et un problème de tas, mais bon…

Pour les sceptiques voici un exemple :
(jouer avec GROSCHIFFRE car le comportement dépend du PC...)

Bah écoute, je reste sceptique.
Chez moi ton programme fais ce qu'il doit faire : il réserve toute la mémoire (swap comprise) puis se fait violemment latter la face par le kernel.
Normal quoi.
Sinon pour des tailles que je supporte tout va bien, aucun problème d'aucune sorte (si on néglige la fuite de mémoire dû à l'absence de free() bien entendu).

Dernière modification par grim7reaper (Le 11/06/2010, à 20:14)

Hors ligne

#8 Le 11/06/2010, à 20:49

superZozo

Re : [Résolu] langage C, dépassement de tas sur gros tableaux...

Bon voilà un code qui plante (chez moi).

J'ai commenté une partie de la fonction "chargement". Dans ces conditions, le programme marche jusqu'au bout.
Quand je décommente, j'ai l'erreur de segmentation, mais avant l'execution de cette partie, sur la première ligne de la fonction chargement (  81:   printf("ok\n"); ) lol

Le fait d'avoir ou pas les fichiers de données ne change rien

main.c

//includes
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <gtk/gtk.h>//gtk+


#include "utils.h"
#include "main.h"

//variables globales
//--- objets ---//
objet* Objets;
ligne* Lignes;
etoile_simple* Etoiles_s;
ngcIc* deepSkyOs;
galaxie* Galaxies;
nebuleuse* Nebuleuses;
nebul_planet* NebPlanet;
open_cluster* AmasOuverts;
glob_cluster* AmasGlobul;

GUI* gui;

int main(int argc, char ** argv)
{
    printf("*Bienvenue **************************************************\n\n");
    allocations();//allocations mémoire

    //initialisation
    gtk_init(&argc,&argv);

    chargements();//chargement des objets célestes

    gtk_main();//boucle GTK+

    printf("sortie.\n");//fin
    return EXIT_SUCCESS;
}

/********************************
* allocation dynamique pour les
* grands tableaux
********************************/
void allocations(void)
{
    //objets
    Objets = malloc((nEtoilesSimples+nObjNGC)*sizeof(objet));
    //lignes
    Lignes = malloc(nLignes*sizeof(ligne));

    //étoiles
    Etoiles_s = malloc(nEtoilesSimples*sizeof(etoile_simple));

    //deep sky objects
    deepSkyOs = malloc(nObjNGC*sizeof(ngcIc));
    //galaxies...
    Galaxies = malloc(nGalaxies*sizeof(galaxie));
    Nebuleuses = malloc(nNebuleuses*sizeof(nebuleuse));
    NebPlanet = malloc(nNebulPlanet*sizeof(nebul_planet));
    AmasOuverts = malloc(nAmasOuverts*sizeof(open_cluster));
    AmasGlobul = malloc(nAmasGlobulaires*sizeof(glob_cluster));

    //gui
    gui = malloc(sizeof(GUI));
}

/****************************
* chargement des fichiers
****************************/
void chargements(void)
{
    etoile_simple* point2 = Etoiles_s;
    ngcIc* ptDso = deepSkyOs;

    int i,j,gal,neb,nebP,OClus,GClus;
    double angleA, angleB;
    double fraction, ad, dec;
    printf("ok\n");

    //interface graphique du chargement
    gui->fenChargement = gtk_window_new(GTK_WINDOW_POPUP);//fenetre
    gtk_window_set_position(GTK_WINDOW(gui->fenChargement), GTK_WIN_POS_CENTER_ALWAYS);
    gtk_window_set_default_size(GTK_WINDOW(gui->fenChargement), 180, 80);

    gui->vboxCharg = gtk_vbox_new(TRUE, 0);//vbox

    gui->lab1Charg = gtk_label_new("<big><span weight=\"heavy\">cartographie</span> \
        </big>\n<i>progression</i>");//label1
    gtk_label_set_use_markup(GTK_LABEL(gui->lab1Charg), TRUE);
    gtk_label_set_justify (GTK_LABEL(gui->lab1Charg), GTK_JUSTIFY_LEFT);

    gui->barProg = gtk_progress_bar_new();//barre de progression
    gtk_widget_set_size_request (GTK_WIDGET(gui->barProg),80, 40);
    gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(gui->barProg), 0.0);
    //gtk_grab_add(GTK_WIDGET(barProg));

    gui->lab2Charg = gtk_label_new("etoiles...");//label2

    gtk_container_add(GTK_CONTAINER(gui->fenChargement), gui->vboxCharg);
    gtk_box_pack_start(GTK_BOX(gui->vboxCharg), gui->lab1Charg, FALSE, TRUE, 4);
    gtk_box_pack_start(GTK_BOX(gui->vboxCharg), gui->barProg, FALSE, FALSE, 10);
    gtk_box_pack_start(GTK_BOX(gui->vboxCharg), gui->lab2Charg, TRUE, TRUE, 4);

    //affichage
    gtk_widget_show_all(gui->fenChargement);
/* <---------------------------------------------------------------- décommenter ici
    //chargement du fichier des données étoiles
    FILE* starFile  = fopen("stars2.dat","rb");
    if(starFile == NULL)
        printf("echec de l'ouverture du fichier etoiles 2\n");
    else{
        printf("ouverture du fichier etoiles 2\n");

        for(i=0;i<nEtoilesSimples;i++)
        {//lecture
            fread(point2,sizeof(etoile_simple),1,starFile);
            point2++;

            if(i%1000==0.){//tous les 1000, on met a jour la barre de progression
                fraction = (double)i/(double)(nEtoilesSimples);
                gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(gui->barProg), fraction);//mise a jour de la barre de progression
                gtk_main_iteration ();
            }
        }
        //fin
        fclose(starFile);//fermeture du fichier
    }

    //NGC & IC
    gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(gui->barProg), 0);//remise a 0 de la barre de progression
    gtk_label_set_label(GTK_LABEL(gui->lab2Charg), "NGC, IC....");//label

    FILE* ngcicFile = fopen("dso.dat","rb");

    if(ngcicFile == NULL)
        printf("echec de l'ouverture du fichier ciel profond\n");
    else{
        printf("ouverture du fichier ciel profond\n");

        for(i=0;i<nObjNGC;i++)
        {//lecture
            fread(ptDso,sizeof(ngcIc),1,ngcicFile);
            ptDso++;
            if(i%100 ==0.){
                fraction = (double)i/(double)(nObjNGC);
                gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(gui->barProg), fraction);//mise a jour de la barre de progression
                gtk_main_iteration ();
            }
        }
        fclose(ngcicFile);
    }


    // traitements
    printf("traitement des donnees...\n");
    gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(gui->barProg), 0);//remise a 0 de la barre de progression
    gtk_label_set_label(GTK_LABEL(gui->lab2Charg), "traitement....");//label

    //passage en coordonnees cartesiennes *************

    for(i=0;i<nEtoilesSimples;i++)//
    {

        ad =  Etoiles_s[i].RA * PI / 180.; //ascension droite en radian
        dec = PI/2.0 - Etoiles_s[i].DEC * PI /180.0;//declinaison en radian !!! car 0 = "pole nord" !!!

        Objets[i].y = rho*cos(dec);
        Objets[i].x = rho*sin(dec)*cos(ad);
        Objets[i].z = -rho*sin(dec)*sin(ad);
        Objets[i].taille = 0.08*pow(10.0,0.5-0.2*Etoiles_s[i].mag);//0.1*... ?
        Objets[i].type = ETOILE;
        Objets[i].ref.ets = &Etoiles_s[i];
    }
    gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(gui->barProg), 0.2);//barre de progression

    //initialisation compteurs
    gal = 0;
    neb =0;
    nebP =0;
    OClus =0;
    GClus =0;

    for(i=0;i<nObjNGC;i++)
    {
        ad = deepSkyOs[i].RA * PI /12.0;
        dec = PI/2.0 - deepSkyOs[i].DEC * PI /180.0;

        Objets[i+nEtoilesSimples].y = rho*cos(dec);
        Objets[i+nEtoilesSimples].x = rho*sin(dec)*cos(ad);
        Objets[i+nEtoilesSimples].z = -rho*sin(dec)*sin(ad);

        //tri des noms : Messier -> NGC -> IC ->... car on affiche que le premier
        for(j=0;j<12;j++)
        {
            if(startChar(deepSkyOs[i].noms[j],"IC ",3))swapChar(deepSkyOs[i].noms[j],deepSkyOs[i].noms[0]);
        }
        for(j=0;j<12;j++)
        {
            if(startChar(deepSkyOs[i].noms[j],"NGC ",4))swapChar(deepSkyOs[i].noms[j],deepSkyOs[i].noms[0]);
        }
        for(j=0;j<12;j++)
        {
            if(startChar(deepSkyOs[i].noms[j],"M ",2))swapChar(deepSkyOs[i].noms[j],deepSkyOs[i].noms[0]);
        }

        if(deepSkyOs[i].type == 1) //Galaxies
        {
            Galaxies[gal].ref = &deepSkyOs[i];
            Objets[i+nEtoilesSimples].type = GALAXIE;
            Objets[i+nEtoilesSimples].ref.gal = &Galaxies[gal];
            Objets[i+nEtoilesSimples].taille = 0.038 - deepSkyOs[i].mag * 0.002;//?

            if(deepSkyOs[i].PA == -1000.)//on ne connait pas PA
            {
                if(deepSkyOs[i].x > 0.){//on connait x
                    angleA = rho * tan(deepSkyOs[i].x / 3437.8);
                    for(j=0;j<20;j++)
                    {
                        Galaxies[gal].pt[j][0] = rho;
                        Galaxies[gal].pt[j][1] = angleA * sin(j * PI/10.);
                        Galaxies[gal].pt[j][2] = angleA * cos(j * PI/10.);

                        rotationX3(Galaxies[gal].pt[j], -PI* deepSkyOs[i].PA /180. , -PI* deepSkyOs[i].DEC /180., PI* deepSkyOs[i].RA /12.);

                        Galaxies[gal].pt[j][2] *= -1;
                    }
                }else{//on ne connait rien
                    ;
                }
            }else{//on connait tout...
                angleA = rho * tan(deepSkyOs[i].x / 3437.8);
                angleB = rho * tan(deepSkyOs[i].y / 3437.8);

                for(j=0;j<20;j++)
                {
                    Galaxies[gal].pt[j][0] = rho;
                    Galaxies[gal].pt[j][1] = angleA * sin(j * PI/10.);
                    Galaxies[gal].pt[j][2] = angleB * cos(j * PI/10.);

                    rotationX3(Galaxies[gal].pt[j], -PI* deepSkyOs[i].PA /180. , -PI* deepSkyOs[i].DEC /180., PI* deepSkyOs[i].RA /12.);

                    Galaxies[gal].pt[j][2] *= -1;
                }
            }
            gal++;
        }
        if(deepSkyOs[i].type == 2 || deepSkyOs[i].type == 6) //Nébuleuses
        {

            Nebuleuses[neb].ref = &deepSkyOs[i];
            Objets[i+nEtoilesSimples].type = NEBULEUSE;
            Objets[i+nEtoilesSimples].ref.nebu = &Nebuleuses[neb];
            Objets[i+nEtoilesSimples].taille = 0.038 - deepSkyOs[i].mag * 0.002;//?
            if(deepSkyOs[i].mag < 12.)Objets[i+nEtoilesSimples].taille = 0.014;//?

            if(deepSkyOs[i].x > 0.){//on connait x
                angleA = rho * tan(deepSkyOs[i].x / 3437.8);
                for(j=0;j<4;j++)
                {
                    Nebuleuses[neb].pt[j][0] = rho;
                    Nebuleuses[neb].pt[j][1] = angleA * sin(PI/4. + j * PI/2.);
                    Nebuleuses[neb].pt[j][2] = angleA * cos(PI/4. + j * PI/2.);

                    rotationX3(Nebuleuses[neb].pt[j], 0., -PI* deepSkyOs[i].DEC /180., PI* deepSkyOs[i].RA /12.);

                    Nebuleuses[neb].pt[j][2] *= -1.;
                }
            }
            neb++;
        }
        if(deepSkyOs[i].type == 3) //nebuleuse planetaire
        {
            NebPlanet[nebP].ref = &deepSkyOs[i];
            Objets[i+nEtoilesSimples].type = NEBUL_PLANET;
            Objets[i+nEtoilesSimples].ref.neb_planet = &NebPlanet[nebP];
            Objets[i+nEtoilesSimples].taille = 0.038 - deepSkyOs[i].mag * 0.002;//?
            if(deepSkyOs[i].mag < 12.)Objets[i+nEtoilesSimples].taille = 0.014;

            if(deepSkyOs[i].x > 0.){//on connait x
                NebPlanet[nebP].rayon = rho * tan(deepSkyOs[i].x / 1718.9);

                NebPlanet[nebP].pt[0] = rho;
                NebPlanet[nebP].pt[1] = 0;
                NebPlanet[nebP].pt[2] = NebPlanet[nebP].rayon;

                rotationX3(NebPlanet[nebP].pt, 0., -PI* deepSkyOs[i].DEC /180., PI* deepSkyOs[i].RA /12.);
                NebPlanet[nebP].pt[2] *= -1.;
            }
            nebP++;
        }
        if(deepSkyOs[i].type == 4) //amas ouvert
        {
            AmasOuverts[OClus].ref = &deepSkyOs[i];
            Objets[i+nEtoilesSimples].type = OPEN_CLUSTER;
            Objets[i+nEtoilesSimples].ref.o_clust = &AmasOuverts[OClus];
            Objets[i+nEtoilesSimples].taille = 0.038 - deepSkyOs[i].mag * 0.002;//?
            if(deepSkyOs[i].mag < 12.)Objets[i+nEtoilesSimples].taille = 0.014;

            if(deepSkyOs[i].x > 0.){//on connait x
                angleA = rho * tan(deepSkyOs[i].x / 6875.5);
                AmasOuverts[OClus].rayon = angleA;
                for(j=0;j<5;j++)
                {
                    AmasOuverts[OClus].pt[j][0] = rho;
                    AmasOuverts[OClus].pt[j][1] = angleA * sin(2 * j * PI/5.);
                    AmasOuverts[OClus].pt[j][2] = angleA * cos(2 * j * PI/5.);

                    rotationX3(AmasOuverts[OClus].pt[j], 0., -PI* deepSkyOs[i].DEC /180., PI* deepSkyOs[i].RA /12.);

                    AmasOuverts[OClus].pt[j][2] *= -1.;
                }
            }
            OClus++;
        }
        if(deepSkyOs[i].type == 5) //amas globulaire
        {
            AmasGlobul[GClus].ref = &deepSkyOs[i];
            Objets[i+nEtoilesSimples].type = GLOB_CLUSTER;
            Objets[i+nEtoilesSimples].ref.g_clust = &AmasGlobul[GClus];
            Objets[i+nEtoilesSimples].taille = 0.038 - deepSkyOs[i].mag * 0.002;//?
            if(deepSkyOs[i].mag < 12.)Objets[i+nEtoilesSimples].taille = 0.014;

            if(deepSkyOs[i].x > 0.){//on connait x
                angleA = rho * tan(deepSkyOs[i].x / 3437.8);
                AmasGlobul[GClus].rayon = angleA;
                for(j=0;j<8;j++)
                {
                    AmasGlobul[GClus].pt[j][0] = rho;
                    AmasGlobul[GClus].pt[j][1] = angleA * sin(PI/8. + j * PI/4.);
                    AmasGlobul[GClus].pt[j][2] = angleA * cos(PI/8. + j * PI/4.);

                    rotationX3(AmasGlobul[GClus].pt[j], 0., -PI* deepSkyOs[i].DEC /180., PI* deepSkyOs[i].RA /12.);

                    AmasGlobul[GClus].pt[j][2] *= -1.;
                }
            }
            GClus++;
        }

    }


    gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(gui->barProg), 0.3);//barre de progression

    //indexation et kd tree *****************************
    //Point **stars = (Point**) malloc((nEtoiles+nObjNGC)*sizeof(Point*));//tableau de pointeurs sur struct Point (points a deux dimensions a indexer + magnitude)
    Point3D stars[nEtoilesSimples+nObjNGC];
    for(i=0;i<nEtoilesSimples;i++){//points a deux dimensions coordonnees spherique
        stars[i][0]=(Etoiles_s[i].RA -180.0) * PI / 180.0; // -pi<ad<pi
        stars[i][1]=PI/2.0 - Etoiles_s[i].DEC * PI /180.0;// 0<dec<pi
        stars[i][2]=Etoiles_s[i].mag;
    }
    for(i=0;i<nObjNGC;i++){
        stars[i+nEtoilesSimples][0]=(deepSkyOs[i].RA -12.0) * PI / 12.0; // -pi<ad<pi
        stars[i+nEtoilesSimples][1]=PI/2.0 - deepSkyOs[i].DEC * PI /180.0;// 0<dec<pi
        stars[i+nEtoilesSimples][2]=deepSkyOs[i].mag;
    }

*/ // <------------------------------------------------------------------------------------------------------------------------------------fin ici
    printf("fin de l'acquisition\n");
    //gtk_grab_remove(barProg);
    gtk_widget_destroy(gui->fenChargement);
}

void rotationX3 (Point3D P, float PA, float DEC, float RA)
{
    ;
}

main.h

void allocations(void);
void chargements(void);
void constructionGUI(void);

void rotationX3 (Point3D P, float PA, float DEC, float RA);

typedef struct GUI_
{
    //fenetre de chargement
    GtkWidget* fenChargement;//fenetre
    GtkWidget* vboxCharg;//layout
    GtkWidget* lab1Charg;//label titre
    GtkWidget* barProg;//barre de progression
    GtkWidget* lab2Charg;//label2 étape en cours
} GUI;

utils.c

#include "utils.h"

/**********************
* intervertie 2 chaines
**********************/
void swapChar(char* a, char* b)
{
    int i;
    char c;
    for(i=0;i<20;i++)
    {
        c = b[i];
        b[i] = a[i];
        a[i] = c;
    }
}

/**********************
* compare 2 chaines
* n premiers caractères
**********************/
int startChar(char* a, char* b, int n)//compare le début
{
    int i;
    int test = 1;
    for(i = 0;i< n; i++)
    {
        if(a[i] != b[i])
        {
            test =0;
            break;
        }
    }
    return test;
}

utils.h

/*************
* constantes *
*************/

#define nEtoilesSimples 863885 //étoiles affichées // <----------------------------------------- c'est en augmentant ici que les ennuis commencent...
#define nObjNGC 11887 //nombre d'objets NGC
#define nNoms 46592 //nombre de noms dans la liste de recherche
#define nGalaxies 10611 //nombre de galaxies
#define nNebuleuses 303 //nebuleuses 251+52
#define nNebulPlanet 130 //nebuleuses planetaires
#define nAmasOuverts 720
#define nAmasGlobulaires 122
#define nBlocsEtoiles 512 //nombre de blocs indexés
#define nLignes 0 //716 //lignes constellations

#define rho 20.0 //distance au centre des objets (coordonnées sphériques)
#define PI 3.1415926535897932384626433832795 //pi

/**********************
* stuctures utilisées *
**********************/

typedef double Point3D[3];
typedef double Point2D[2];

//--- objets ---//
typedef struct
{
    Point3D pt[2];
} ligne;

//types
enum TYPE {ETOILE,GALAXIE,NEBULEUSE,NEBUL_PLANET,OPEN_CLUSTER,GLOB_CLUSTER};

typedef struct//une etoile
{
    int id;//identifiant
    float RA;//Right Ascension
    float DEC;//Declinaison
    float mag;//visual magnitude
    char nom1[24];//nom "arabe"
    char nom2[12];// alpha constell...
}
etoile;

typedef struct//etoile simple
{
    float RA;
    float DEC;
    float mag;
}
etoile_simple;

typedef struct//objets du ciel profond
{
    int id;//identifiant
    enum TYPE type;//galaxie , amas
    float RA;
    float DEC;
    float mag;

    float x;//dimensions
    float y;
    float PA;

    char noms[12][20];//noms
}
ngcIc;

typedef struct //galaxie
{
    Point3D pt[20]; //points de l'ellipse
    ngcIc* ref;
}
galaxie;
typedef struct //nebuleuse
{
    Point3D pt[4];
    ngcIc* ref;
}
nebuleuse;
typedef struct //nebuleuse planetaire
{
    double rayon;
    Point3D pt;
    ngcIc* ref;
}
nebul_planet;
typedef struct
{
    double rayon;
    Point3D pt[5];
    ngcIc* ref;
}
open_cluster;
typedef struct
{
    double rayon;
    Point3D pt[8];
    ngcIc* ref;
}
glob_cluster;

typedef union //reference = étoile ou objet
{
    etoile* et;
    etoile_simple* ets;
    galaxie* gal;
    nebuleuse* nebu;
    nebul_planet* neb_planet;
    open_cluster* o_clust;
    glob_cluster* g_clust;
}Ref;

typedef struct //objet à afficher
{
    float x;//coordonnees
    float y;
    float z;
    float taille;//taille

    enum TYPE type;//etoile...
    Ref ref;//pointeur vers un objet quelconque...
}
objet;

//--- fonctions ---//
int equalStrings (char s1[], char s2[]);
void setChar(char* dest, char* val);
void swapChar(char* a, char* b);
int comparChar(char* a, char* b);
int startChar(char* a, char* b, int n);

Il est très possible que sur un autre ordi, le comportement change...

Hors ligne

#9 Le 11/06/2010, à 21:27

grim7reaper

Re : [Résolu] langage C, dépassement de tas sur gros tableaux...

Bon j'ai des symboles de merde dans le source (dû au copier-coller à partir du HTML >.<).
Je n'ai pas de temps à consacrer à leur recherches ce soir, je verrais ça une autre fois (sauf si quelqu'un passe entre temps et résout ton problème wink)

Tu peux toujours passer un coup de GDB et/ou de Valgrind pour avoir des infos.

Dernière modification par grim7reaper (Le 11/06/2010, à 21:36)

Hors ligne

#10 Le 11/06/2010, à 22:56

telliam

Re : [Résolu] langage C, dépassement de tas sur gros tableaux...

salut,
dans ta fonction chargement remplace

 
 Point3D stars[nEtoilesSimples+nObjNGC];

par   

Point3D *stars = (Point3D*) malloc((nEtoilesSimples+nObjNGC)*sizeof(Point3D));

En fait a l'appel de ta fonction 'chargements' il va essayer de prévoir toute la place pour tes variables locales, et vu que la ton tableau stars fait plus de 21 Mo forcément ça tient pas en pile lol

Dernière modification par telliam (Le 11/06/2010, à 22:59)


"- Un intellectuel assis va moins loin qu'un con qui marche."
Maurice Biraud - Un Taxi pour Tobrouk
Michel Audiard

Hors ligne

#11 Le 11/06/2010, à 23:09

superZozo

Re : [Résolu] langage C, dépassement de tas sur gros tableaux...

smile smile smile

Merci ça avance !!!!
j'avais oublié cette partie qui a été modifiée récemment.
Il y a de bonnes chances pour que cela soit ça !!!
J'était tellement perturbé par ces problèmes de heap overflow (que je ne sais pas gérer) que je pensais que le problème se situait plus tôt dans l'éxécution.
C'est là où je vois mes mauvaises connaissances de la compilation. wink

Je vérifie demain que ça passe pour le reste du programme.

Hors ligne

#12 Le 11/06/2010, à 23:18

telliam

Re : [Résolu] langage C, dépassement de tas sur gros tableaux...

vu la taille de tes allocations, penses a bien vérifier tes pointeurs apres le malloc.


"- Un intellectuel assis va moins loin qu'un con qui marche."
Maurice Biraud - Un Taxi pour Tobrouk
Michel Audiard

Hors ligne

#13 Le 12/06/2010, à 10:59

superZozo

Re : [Résolu] langage C, dépassement de tas sur gros tableaux...

OK ça marche !!!

Je n'avais pas pensé à vérifier les tableaux déclarés après la zone de plantage, c'est formateur.
Je teste les pointeurs, mais j'ai chinté ces lignes dans le code que j'ai posté pour faciliter la lecture.

Merci à tous

smile

Hors ligne

#14 Le 12/06/2010, à 11:36

Emmanuel Delahaye

Re : [Résolu] langage C, dépassement de tas sur gros tableaux...

superZozo a écrit :

Bon, ce n'est pas du tout facile "d'isoler" le code. Comme je l'ai dit, on peut déclencher une erreur de segmentation sur n'importe quoi même un simple printf(""); ce qui indique que c'est le tas (heap) et non la pile (stack) qui est écrasé.

Pour les sceptiques voici un exemple :
(jouer avec GROSCHIFFRE car le comportement dépend du PC...)

Ce code est faux. Les tailles allouées sont erronées et il n'y a pas de contrôle.

Ceci fonctionne :

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

/* macros ============================================================== */

#define GROSCHIFFRE 300000

/* constants =========================================================== */
/* types =============================================================== */
/* structures ========================================================== */

typedef struct                  /* objet à afficher */
{
   float x;                     /* coordonnees */
   float y;
   float z;
   float taille;                /* taille */

   void *ref;                   /* pointeur vers un objet quelconque... */
}
objet;

/* private variables =================================================== */

/* private functions =================================================== */

static int allocations (void)
{
   int err = 0;
   int i, j;
   int n = 100;

   unsigned long size = 0;

   objet **GROSTABLEAU = malloc (n * sizeof *GROSTABLEAU);

   if (GROSTABLEAU != NULL)
   {
      size += n * sizeof *GROSTABLEAU;

      for (j = 0; !err && j < n; j++)
      {
         GROSTABLEAU[j] = malloc (GROSCHIFFRE * sizeof *GROSTABLEAU[j]);
         if (GROSTABLEAU[j] != NULL)
         {
            size += GROSCHIFFRE * sizeof *GROSTABLEAU[j];
            printf ("%d (%lu)\n", j, size);
            for (i = 0; i < GROSCHIFFRE; i++)
            {
               GROSTABLEAU[j][i].x = 0.1;
               GROSTABLEAU[j][i].y = 0.1;
               GROSTABLEAU[j][i].z = 0.1;
               GROSTABLEAU[j][i].taille = 100.;
               GROSTABLEAU[j][i].ref = NULL;
            }
         }
         else
         {
            printf ("memory error\n");
            err = 1;
         }
      }
   }
   else
   {
      printf ("memory error\n");
      err = 1;
   }

   if (!err)
   {
      printf ("%lu bytes allocated\n", size);
   }
   return err;
}

static void test (void)
{
   printf ("convaincu ?\n");
}

/* entry points ======================================================== */

int main (void)
{
   int err;
   printf ("démarrage\n");

   err = allocations ();        /* allocations mémoire */
   if (!err)
   {
      test ();
      printf ("sortie.\n");     /* fin */
   }

   return EXIT_SUCCESS;
}

ce qui produit :

dÚmarrage
0 (6000400)
1 (12000400)
2 (18000400)
3 (24000400)
4 (30000400)
5 (36000400)
6 (42000400)
7 (48000400)
8 (54000400)
9 (60000400)
10 (66000400)
11 (72000400)
12 (78000400)
13 (84000400)
14 (90000400)
15 (96000400)
16 (102000400)
17 (108000400)
18 (114000400)
19 (120000400)
20 (126000400)
21 (132000400)
22 (138000400)
23 (144000400)
24 (150000400)
25 (156000400)
26 (162000400)
27 (168000400)
28 (174000400)
29 (180000400)
30 (186000400)
31 (192000400)
32 (198000400)
33 (204000400)
34 (210000400)
35 (216000400)
36 (222000400)
37 (228000400)
38 (234000400)
39 (240000400)
40 (246000400)
41 (252000400)
42 (258000400)
43 (264000400)
44 (270000400)
45 (276000400)
46 (282000400)
47 (288000400)
48 (294000400)
49 (300000400)
50 (306000400)
51 (312000400)
52 (318000400)
53 (324000400)
54 (330000400)
55 (336000400)
56 (342000400)
57 (348000400)
58 (354000400)
59 (360000400)
60 (366000400)
61 (372000400)
62 (378000400)
63 (384000400)
64 (390000400)
65 (396000400)
66 (402000400)
67 (408000400)
68 (414000400)
69 (420000400)
70 (426000400)
71 (432000400)
72 (438000400)
73 (444000400)
74 (450000400)
75 (456000400)
76 (462000400)
77 (468000400)
78 (474000400)
79 (480000400)
80 (486000400)
81 (492000400)
82 (498000400)
83 (504000400)
84 (510000400)
85 (516000400)
86 (522000400)
87 (528000400)
88 (534000400)
89 (540000400)
90 (546000400)
91 (552000400)
92 (558000400)
93 (564000400)
94 (570000400)
95 (576000400)
96 (582000400)
97 (588000400)
98 (594000400)
99 (600000400)
600000400 bytes allocated
convaincu ?
sortie.

Process returned 0 (0x0)   execution time : 1.728 s
Press any key to continue.

Par contre, avec 3 000 000, ça rame, parce que le swap se met en route à partir de 24. (je n'ai que 2 Go de mémoire)

Il faudrait aussi passer 'size' en unsigned long long (C99).

Dernière modification par Emmanuel Delahaye (Le 12/06/2010, à 14:43)


C is a sharp tool!

http://www.bien-programmer.fr/index.php

Hors ligne

#15 Le 12/06/2010, à 14:07

telliam

Re : [Résolu] langage C, dépassement de tas sur gros tableaux...

la publicité pour son propre site est pas interdite ?? big_smiletongue


"- Un intellectuel assis va moins loin qu'un con qui marche."
Maurice Biraud - Un Taxi pour Tobrouk
Michel Audiard

Hors ligne

#16 Le 12/06/2010, à 14:33

Emmanuel Delahaye

Re : [Résolu] langage C, dépassement de tas sur gros tableaux...

telliam a écrit :

la publicité pour son propre site est pas interdite ?? big_smiletongue

La charte dit : "Il est interdit de faire la promotion de sites personnels (blogs, forum, etc.) sans aucune relation avec les logiciels libres en général ou Ubuntu en particulier."

Sur mon site, je parle du langage C et de la programmation en général. C'est mal ?

Dernière modification par Emmanuel Delahaye (Le 12/06/2010, à 14:34)


C is a sharp tool!

http://www.bien-programmer.fr/index.php

Hors ligne

#17 Le 12/06/2010, à 16:04

helly

Re : [Résolu] langage C, dépassement de tas sur gros tableaux...

Non, tu fais bien wink


Archlinux-wmii-dwb.
Un problème résolu ? Faites le savoir en mettant [résolu] à côté du titre de votre topic.
Un problème non résolu ? Faites le savoir en insultant ceux qui cherchent à vous aider.
Un site bleu super remasterised©, un wiki cherchant des volontaires pour traduire un site.

Hors ligne

#18 Le 13/06/2010, à 01:04

telliam

Re : [Résolu] langage C, dépassement de tas sur gros tableaux...

Emmanuel Delahaye a écrit :
telliam a écrit :

la publicité pour son propre site est pas interdite ?? big_smiletongue

La charte dit : "Il est interdit de faire la promotion de sites personnels (blogs, forum, etc.) sans aucune relation avec les logiciels libres en général ou Ubuntu en particulier."

Sur mon site, je parle du langage C et de la programmation en général. C'est mal ?

non non du tout, d'ou mon emploi des smileys d'ailleurs smile


"- Un intellectuel assis va moins loin qu'un con qui marche."
Maurice Biraud - Un Taxi pour Tobrouk
Michel Audiard

Hors ligne

#19 Le 13/06/2010, à 11:44

superZozo

Re : [Résolu] langage C, dépassement de tas sur gros tableaux...

@ Emmanuel Delahaye.

Tu as tout à fait raison, pour la forme du code (j'ai été au plus vite pour mon exemple) tongue.
Le problème est surtout qu'il ne s'agit pas exactement du même type d'erreur entre les deux exemples que je donne.

Hors ligne

#20 Le 04/07/2010, à 15:05

nesthib

Re : [Résolu] langage C, dépassement de tas sur gros tableaux...

@Emmanuel Delahaye : pas de soucis pour mettre un lien vers ton site, à condition de ne pas participer uniquement à cette fin. Mets ton lien dans la signature pas dans chaque message que tu postes. merci


GUL Bordeaux : GirollServices libres : TdCT.org
Hide in your shell, scripts & astuces :  applications dans un tunnelsmart wgettrouver des pdfinstall. auto de paquetssauvegarde auto♥ awk
  ⃛ɹǝsn xnuᴉꞁ uʍop-ǝpᴉsdn

Hors ligne