#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")
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...
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 .
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.
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...
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"); )
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 )
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
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...
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.
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
Hors ligne
#14 Le 12/06/2010, à 11:36
- Emmanuel Delahaye
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...)
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 ??
"- 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...
la publicité pour son propre site est pas interdite ??
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
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...
telliam a écrit :la publicité pour son propre site est pas interdite ??
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
"- 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) .
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 : Giroll – Services libres : TdCT.org
Hide in your shell, scripts & astuces : applications dans un tunnel – smart wget – trouver des pdf – install. auto de paquets – sauvegarde auto – ♥ awk
⃛ɹǝsn xnuᴉꞁ uʍop-ǝpᴉsdn
Hors ligne