Erreur de segmentation ...
Résolu
martiennette
Messages postés
2
Date d'inscription
Statut
Membre
Dernière intervention
-
Mahmah Messages postés 496 Date d'inscription Statut Membre Dernière intervention -
Mahmah Messages postés 496 Date d'inscription Statut Membre Dernière intervention -
Bonjour,
j'écris un petit programme en C pour lire un fichier binaire très volumineux, qui contient un vecteur très long, et le transformer en matrice 3 D.
Tou se passe bien jusqu'à ce que je m'attaque à des vraiment gros fichiers, typiquement, quand je depasse environ 500 000 lignes (quand le paramètre nslice depasse 10, et donc le nombre total de ligne pass au dessus de 456020).
Est ce qu'il y a une limite de taille quelque part, que je ne vois pas ?
je ne vois pas où ça bloque...
Merci d'avance
marie
le programme:
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <cstdio>
using namespace std;
#define ncar 151
#define nslice 10
int main()
{
// Indices pour trier data
long int i,j,xi,yi,si,s;
long int Ndatatot;
// Données sur le format du fichier
int NdataR,NdataC;
NdataR=NdataC=ncar*ncar;
Ndatatot=ncar*ncar*nslice*2;
cout << "Ndatatot : " << Ndatatot << endl;
double data[ncar*ncar*nslice*2]={0};
double dataout[ncar*ncar*nslice*2]={0};
// Données sur le format de sortie
double FieldR[ncar][ncar][nslice]={0};
double FieldC[ncar][ncar][nslice]={0};
// Ouverture du fichier binaire à traiter
FILE* fichier = NULL;
fichier=fopen("templateTD.out.fld","rb");
// templateTD.out.fld
printf("opened \n");
// Lecture du fichier
if (fichier != NULL)
{
for(i=0;i<Ndatatot;i++)
{
// fscanf(fichier,"%lf", &data[i]);
fread(&data[i],sizeof(double),1,fichier);
}
printf("Data %e, %e, %e \n", data[0], data[1],data[2]);
fclose(fichier);
}
// Lecture des données du fichier et écriture en matrices
for(s=0;s<nslice;s++)
{
si=s;
for(i=0;i<NdataR;i++)
{
xi=floor(i/ncar);
yi=i-ncar*(floor(i/ncar));
// si=0;
FieldR[xi][yi][si]=data[i+s*ncar*ncar*2];
}
cout << "fieldR : " << FieldR[0][0][s] << endl;
// cout << "fieldR : " << FieldR[0][1][0] << endl;
// cout << "fieldR : " << FieldR[0][2][0] << endl;
for(j=NdataR;j<NdataR+NdataC;j++)
{
xi=floor((j-NdataR)/ncar);
yi=j-ncar*(floor((j)/ncar));
// si=0;
FieldC[xi][yi][si]=data[j+s*ncar*ncar*2];
}
// cout << "fieldC : " << FieldC[0][0][0] << endl;
// cout << "fieldC : " << data[NdataR] << endl;
}
// Ecriture de la matrice en une seule colonne
for(s=0;s<nslice;s++)
{
si=s;
for(i=0;i<NdataR;i++)
{
xi=floor(i/ncar);
yi=i-ncar*(floor(i/ncar));
// si=0;
dataout[i+s*ncar*ncar*2]=FieldR[xi][yi][si];
// cout << "datai " << dataout[i] << endl;
// cout << "fieldR : " << FieldR[xi][yi][si] << endl;
// cout << "dataout : " << dataout[0] << endl;
}
for(j=NdataR;j<NdataR+NdataC;j++)
{
xi=floor((j-NdataR)/ncar);
yi=j-ncar*(floor(j/ncar));
// si=0;
dataout[j+s*ncar*ncar*2]=FieldC[xi][yi][si];
}
}
// Ecriture de la colonne dans un fichier
cout << "Ecriture" << endl;
FILE* fichier2 = NULL;
fichier2=fopen("dataout.txt","w");
if (fichier2 != NULL)
{
for(i=0;i<Ndatatot;i++)
{
fprintf(fichier2,"%e \n", dataout[i]);
}
fprintf(fichier2,"\n");
fclose(fichier2);
}
printf("Data %e, %e, %e \n", dataout[0], dataout[1],dataout[2]);
return 0;
}
j'écris un petit programme en C pour lire un fichier binaire très volumineux, qui contient un vecteur très long, et le transformer en matrice 3 D.
Tou se passe bien jusqu'à ce que je m'attaque à des vraiment gros fichiers, typiquement, quand je depasse environ 500 000 lignes (quand le paramètre nslice depasse 10, et donc le nombre total de ligne pass au dessus de 456020).
Est ce qu'il y a une limite de taille quelque part, que je ne vois pas ?
je ne vois pas où ça bloque...
Merci d'avance
marie
le programme:
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <cstdio>
using namespace std;
#define ncar 151
#define nslice 10
int main()
{
// Indices pour trier data
long int i,j,xi,yi,si,s;
long int Ndatatot;
// Données sur le format du fichier
int NdataR,NdataC;
NdataR=NdataC=ncar*ncar;
Ndatatot=ncar*ncar*nslice*2;
cout << "Ndatatot : " << Ndatatot << endl;
double data[ncar*ncar*nslice*2]={0};
double dataout[ncar*ncar*nslice*2]={0};
// Données sur le format de sortie
double FieldR[ncar][ncar][nslice]={0};
double FieldC[ncar][ncar][nslice]={0};
// Ouverture du fichier binaire à traiter
FILE* fichier = NULL;
fichier=fopen("templateTD.out.fld","rb");
// templateTD.out.fld
printf("opened \n");
// Lecture du fichier
if (fichier != NULL)
{
for(i=0;i<Ndatatot;i++)
{
// fscanf(fichier,"%lf", &data[i]);
fread(&data[i],sizeof(double),1,fichier);
}
printf("Data %e, %e, %e \n", data[0], data[1],data[2]);
fclose(fichier);
}
// Lecture des données du fichier et écriture en matrices
for(s=0;s<nslice;s++)
{
si=s;
for(i=0;i<NdataR;i++)
{
xi=floor(i/ncar);
yi=i-ncar*(floor(i/ncar));
// si=0;
FieldR[xi][yi][si]=data[i+s*ncar*ncar*2];
}
cout << "fieldR : " << FieldR[0][0][s] << endl;
// cout << "fieldR : " << FieldR[0][1][0] << endl;
// cout << "fieldR : " << FieldR[0][2][0] << endl;
for(j=NdataR;j<NdataR+NdataC;j++)
{
xi=floor((j-NdataR)/ncar);
yi=j-ncar*(floor((j)/ncar));
// si=0;
FieldC[xi][yi][si]=data[j+s*ncar*ncar*2];
}
// cout << "fieldC : " << FieldC[0][0][0] << endl;
// cout << "fieldC : " << data[NdataR] << endl;
}
// Ecriture de la matrice en une seule colonne
for(s=0;s<nslice;s++)
{
si=s;
for(i=0;i<NdataR;i++)
{
xi=floor(i/ncar);
yi=i-ncar*(floor(i/ncar));
// si=0;
dataout[i+s*ncar*ncar*2]=FieldR[xi][yi][si];
// cout << "datai " << dataout[i] << endl;
// cout << "fieldR : " << FieldR[xi][yi][si] << endl;
// cout << "dataout : " << dataout[0] << endl;
}
for(j=NdataR;j<NdataR+NdataC;j++)
{
xi=floor((j-NdataR)/ncar);
yi=j-ncar*(floor(j/ncar));
// si=0;
dataout[j+s*ncar*ncar*2]=FieldC[xi][yi][si];
}
}
// Ecriture de la colonne dans un fichier
cout << "Ecriture" << endl;
FILE* fichier2 = NULL;
fichier2=fopen("dataout.txt","w");
if (fichier2 != NULL)
{
for(i=0;i<Ndatatot;i++)
{
fprintf(fichier2,"%e \n", dataout[i]);
}
fprintf(fichier2,"\n");
fclose(fichier2);
}
printf("Data %e, %e, %e \n", dataout[0], dataout[1],dataout[2]);
return 0;
}
A voir également:
- Erreur de segmentation ...
- Erreur 0x80070643 - Accueil - Windows
- Erreur 4101 france tv - Forum Lecteurs et supports vidéo
- J'aime par erreur facebook notification - Forum Facebook
- Code erreur f3500-31 ✓ - Forum Bbox Bouygues
- Java code erreur 1603 ✓ - Forum Windows
3 réponses
Oui, tout simplement
La taille de mes matrices etait trop grosse.
je m'en suis finalement sortie en faisant un traitement bout par bout de mes données, ce qui evite de garder en mémoire de trop grosses matrices.
merci
marie
La taille de mes matrices etait trop grosse.
je m'en suis finalement sortie en faisant un traitement bout par bout de mes données, ce qui evite de garder en mémoire de trop grosses matrices.
merci
marie
Bonjour,
En effet, j'avais fait un léger test hier soir et plouf !
Le problème n'est pas la taille mais l'endroit. En temps que variables locales d'une fonction, tes tableaux sont stockés dans la pile. C'est comme une pile d'assiette, on stocke en ajoutant au dessus chaque fois, elles sont toutes visibles (accessibles) mais on ne peut les retirer qu'à partir du dessus de la pile.
Si vous savez ce qu'est la pile vous pouvez sauter le paragraphe suivant.
Cette pile d'exécution sert au bon déroulement du programme pour:
- stocker les variables locales.
- stocker les paramètres lors d'appels de fonctions.
- stocker les paramètres de convention d'appel des fonctions. ( On veut appeler une fonction: on stocke la valeur de chaque paramètre dans la pile puis on stocke l'adresse de retour (c'est à dire là où il faudra reprendre quand la fonction fera son return) on stocke l'adresse de la base de la pile (je ne sais plus dans quel ordre avec l'adresse de retour) L'adresse de la base de la pile est simplement décalée pour que chaque fonction puisse utiliser cette adresse comme si la pile n'était que pour elle. Dans le cas des conventions d'appels C++ il y a encore un paramètre supplémentaire mais je ne sais plus lequel. (Mais celà jusitife tout simplement l'incompatibilité des appels et la nécessité du extern "C" pour rendre compatible le C++ avec le C lors d'exports de fonctions.
Pour résoudre le problème et travailler avec les tailles souhaitées pour les tableaux on peut:
Déclarer les tableaux dans l'environnement global (en dehors de toute fonction donc, et c'est ce que je ferais ici car le programme est court)
Ou
Allouer dynamiquement les tableaux.
Et voilou.
M.
En effet, j'avais fait un léger test hier soir et plouf !
Le problème n'est pas la taille mais l'endroit. En temps que variables locales d'une fonction, tes tableaux sont stockés dans la pile. C'est comme une pile d'assiette, on stocke en ajoutant au dessus chaque fois, elles sont toutes visibles (accessibles) mais on ne peut les retirer qu'à partir du dessus de la pile.
Si vous savez ce qu'est la pile vous pouvez sauter le paragraphe suivant.
Cette pile d'exécution sert au bon déroulement du programme pour:
- stocker les variables locales.
- stocker les paramètres lors d'appels de fonctions.
- stocker les paramètres de convention d'appel des fonctions. ( On veut appeler une fonction: on stocke la valeur de chaque paramètre dans la pile puis on stocke l'adresse de retour (c'est à dire là où il faudra reprendre quand la fonction fera son return) on stocke l'adresse de la base de la pile (je ne sais plus dans quel ordre avec l'adresse de retour) L'adresse de la base de la pile est simplement décalée pour que chaque fonction puisse utiliser cette adresse comme si la pile n'était que pour elle. Dans le cas des conventions d'appels C++ il y a encore un paramètre supplémentaire mais je ne sais plus lequel. (Mais celà jusitife tout simplement l'incompatibilité des appels et la nécessité du extern "C" pour rendre compatible le C++ avec le C lors d'exports de fonctions.
Pour résoudre le problème et travailler avec les tailles souhaitées pour les tableaux on peut:
Déclarer les tableaux dans l'environnement global (en dehors de toute fonction donc, et c'est ce que je ferais ici car le programme est court)
Ou
Allouer dynamiquement les tableaux.
double *p = NULL; p = (double*) malloc( X * sizeof( double ) ); // Avec X le nombre de doubles voulus. if ( p!= NULL ) { ... for ( unsigned int i = 0 ; i != X ; i++ ) p[i] = // notation identique à celle des tableaux ... free( p ); // Fin d'utilisation, libération de la mémoire allouée. }
Et voilou.
M.