#1 Le 26/11/2008, à 16:40
- meyus
langage C, capacité mémoire, gestion etc..(erreur de segmentation)
Bonjour,
Voila je fais des simu en langage C et je ne suis pas formé pour la gestion de la mémoire.
Mon probléme, c'est que j'arrive à la taille limite de mes tableaux en double precision, voila comment je les déclare c'est trés simple :
#include <stdio.h>
#include <math.h>
#include "random.h"
#include <gsl/gsl_sf_expint.h>
#define dnu 100.
#define Np 10000
#define Ns 20
#define ds 0.1
#define pi 4.*atan(1.)
#define st 1.
#define Nsimu 100
#define eps 0.0001
FILE*fp;
int main(){
int i,j,nn,cpt;
double S[Ns+2],ct[Ns+2],x,pas,somme,somme2,somm12,dkb,dphi;
double nu,ka[Np+22],pasx,tr[Np+22][Nsimu+2];
double somme3,somme4;
double dtdp,dtdk,dtt,phi,kb,phit,kbt,npx,dphit,dkbt;
double tr_m[Np+22];
double kbs,kbsc,kbsm,phis;
double kb_st,phi_st,cst;
comme on peut le voir la variable Np est grande donc j'ai de grand tableaux, je veux rajouter un tableaux que j'appel tr_mc[Np+22], mais là j'ai "Erreur de segmentation".
comment je peux faire ? je dois allouer de la mémoire ?
Merci de m'aider.
Meyus
Hors ligne
#2 Le 26/11/2008, à 17:25
- jpages
Re : langage C, capacité mémoire, gestion etc..(erreur de segmentation)
Les indices des tableaux commencent à 0 en langage C, donc le dernier indice
de tr_m est Np+21 (pour une taille de Np+22), d'où l'erreur de segmentation.
"Notre liberté se bâtit sur ce qu'autrui ignore de nos existences." (Alexandre Soljénitsyne)
Hors ligne
#3 Le 26/11/2008, à 17:36
- meyus
Re : langage C, capacité mémoire, gestion etc..(erreur de segmentation)
lol non ma question n'est pas d'ou vient l'erreur de segmentation
car je sais que ça vient de la capacité mémoire ! je ne dépasse pas la taille des tableaux mais je dépasse la capacité memoire !
car il tourne sans que je mettes tr_mc[Np+22] dans la déclaration des variables et il mets "Erreur de segmentation' que je la déclare juste !
Hors ligne
#4 Le 26/11/2008, à 17:55
- meyus
Re : langage C, capacité mémoire, gestion etc..(erreur de segmentation)
est ce que un truc comme "alloc" pourrait m'aider ?
Merci
Hors ligne
#5 Le 26/11/2008, à 17:57
- nicolas.sitbon
Re : langage C, capacité mémoire, gestion etc..(erreur de segmentation)
est ce que un truc comme "alloc" pourrait m'aider ?
Merci
Certainement.
Dernière modification par nicolas.sitbon (Le 26/11/2008, à 17:58)
Hors ligne
#6 Le 26/11/2008, à 17:59
- meyus
Re : langage C, capacité mémoire, gestion etc..(erreur de segmentation)
heu et un petit tuto ou quelques exemples pourrait me faire gagner du temps, tu sais où je peux en trouver ?
Merci
Hors ligne
#7 Le 26/11/2008, à 19:25
- tiky
Re : langage C, capacité mémoire, gestion etc..(erreur de segmentation)
lol non ma question n'est pas d'ou vient l'erreur de segmentation
car je sais que ça vient de la capacité mémoire ! je ne dépasse pas la taille des tableaux mais je dépasse la capacité memoire !car il tourne sans que je mettes tr_mc[Np+22] dans la déclaration des variables et il mets "Erreur de segmentation' que je la déclare juste !
Bonsoir,
La pile sous Linux a une taille maximale fixe. La commande limit permet de connaître sa taille en mémoire virtuelle.
Chez moi c'est 8 MB. C'est très grand ! En effet la pile est censée stocker uniquement les appels aux procédures, les arguments de celles-ci et leurs variables locales dès lors que celles-ci sont de petites tailles. Un logiciel de manipulation d'image ne stockera jamais l'image sur laquelle tu travailles dans le segment de la pile. Il utilisera le segment du tas en effectuant des allocations dynamiques.
Tu dépasses nettement la limite rien qu'avec les trois tableaux suivants:
ka, tr et tr_m.
Pour faire une allocation dynamique, tu as l'appel système malloc qui prend en argument la taille de la zone mémoire à allouer dans le tas et retourne un pointeur void * vers cette nouvelle zone.
Il est obligatoire de libérer la mémoire avec l'appel système free qui libère la zone mémoire à l'aide du pointeur passé en argument.
Enfin il est fortement conseillé d'initialiser ton pointeur à NULL si tu ne lui affectes aucune adresse mémoire immédiatement. De même une fois la zone mémoire libérée, il faut initialiser le pointeur à NULL. Si tu effectues un malloc, tu dois tester la valeur du pointeur avec NULL ensuite pour t'assurer que la zone mémoire est bien allouée.
double * ptr = malloc( sizeof( double ) * 100 );
if( ptr != NULL )
{
free( ptr );
ptr = NULL;
}
Dernière modification par tiky (Le 26/11/2008, à 19:33)
Conseil d'expert: il vous faut un dentifrice adapté...
Hors ligne
#8 Le 26/11/2008, à 20:34
- nicolas.sitbon
Re : langage C, capacité mémoire, gestion etc..(erreur de segmentation)
La pile sous Linux a une taille maximale fixe. La commande limit permet de connaître sa taille en mémoire virtuelle.
Chez moi c'est 8 MB.
seulement la pile du thread principal, rien ne t'empêche d'allouer une pile plus grande pour les autres threads.
Pour faire une allocation dynamique, tu as l'appel système malloc qui prend en argument la taille de la zone mémoire à allouer dans le tas et retourne un pointeur void * vers cette nouvelle zone.
Il est obligatoire de libérer la mémoire avec l'appel système free qui libère la zone mémoire à l'aide du pointeur passé en argument.
malloc et free ne sont pas des appels systèmes mais des fonctions de la librairie standard du C, les appels systèmes sous jacents sont brk et mmap de mémoire (sys_*).
double * ptr = malloc( sizeof( double ) * 100 ); if( ptr != NULL ) { free( ptr ); ptr = NULL; }
la forme canonique serait plutôt de la forme:
double * ptr = malloc( 100 * sizeof *ptr); /* généricité */
if( ptr != NULL )
{
/* your code */
free( ptr ), ptr = NULL; /* la ça ne change rien, mais ça montre l'intention d'atomicité */
}
Hors ligne
#9 Le 26/11/2008, à 22:06
- tiky
Re : langage C, capacité mémoire, gestion etc..(erreur de segmentation)
Oui effectivement je ne parlais que pour un seul thread
Je crois que tu as raison pour malloc et free, je vais vérifier.
Pour ta dernière remarque, c'est avant tout une question de goût, je préfère utiliser sizeof( double ) qui est plus parlant d'après moi. De même je préfère mettre ptr = NULL, sur une nouvelle ligne.
Dernière modification par tiky (Le 26/11/2008, à 22:12)
Conseil d'expert: il vous faut un dentifrice adapté...
Hors ligne
#10 Le 26/11/2008, à 22:16
- tiky
Re : langage C, capacité mémoire, gestion etc..(erreur de segmentation)
Je confirme pour malloc() et free(). Maintenant sous Linux, ils appellent des appels systèmes, ce sont donc des appels systèmes indirectement sous Linux.
Conseil d'expert: il vous faut un dentifrice adapté...
Hors ligne
#11 Le 27/11/2008, à 08:02
- nicolas.sitbon
Re : langage C, capacité mémoire, gestion etc..(erreur de segmentation)
Je crois que tu as raison pour malloc et free, je vais vérifier.
voilà la bonne attitude.
Pour ta dernière remarque, c'est avant tout une question de goût, je préfère utiliser sizeof( double ) qui est plus parlant d'après moi.
Plus parlant c'est discutable, moins générique c'est sûr, si demain tu changes le type de ton pointeur, mettons pour un (long double*), tu devras faire 2 modifications, alors qu'avec ma méthode tu n'en fais qu'une.
Hors ligne
#12 Le 27/11/2008, à 15:45
- meyus
Re : langage C, capacité mémoire, gestion etc..(erreur de segmentation)
merci, je viens juste de relire un peu, je vais essaier. Merci car je pense que cela va me servir bcq ds l'avenir !
Hors ligne
#13 Le 29/11/2008, à 15:59
- tiky
Re : langage C, capacité mémoire, gestion etc..(erreur de segmentation)
Plus parlant c'est discutable, moins générique c'est sûr, si demain tu changes le type de ton pointeur, mettons pour un (long double*), tu devras faire 2 modifications, alors qu'avec ma méthode tu n'en fais qu'une.
Oui moins générique c'est indiscutable mais la double modification est tout à fait tolérable car elle s'effectue sur la même ligne et Vim me fait ça comme un grand
Conseil d'expert: il vous faut un dentifrice adapté...
Hors ligne