IdentifiantMot de passe
Loading...
Mot de passe oubli� ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les r�ponses en temps r�el, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

Segmentation fault - Struct d'array


Sujet :

C

  1. #1
    Membre averti
    Homme Profil pro
    Inscrit en
    Novembre 2011
    Messages
    25
    D�tails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Novembre 2011
    Messages : 25
    Par d�faut Segmentation fault - Struct d'array
    Bonjour,

    Je chercher � utiliser un curseur qui fetch des donn�es dans une struct de tableaux (PRO*C) mais j'ai une segmentation fault de c que j'aimerai �lucider.

    Voici la struct que j'utilise :

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     
    /* Peut-être trouver une façon de faire dynamique ... */
     
    #define ARRAY_LENGTH 100
     
    /**************************** Struct definition ************************************************************/
     
    /* Structure de donnée représentant l'ensemble des tableaux utilisés pour stocker les données de rating_score. */
    typedef struct
    {
    	long		PersonIdn[ARRAY_LENGTH];
    	char 		RatingModel[ARRAY_LENGTH][CODE_LENGTH];
    	char		ModelVar[ARRAY_LENGTH][CODE_LENGTH];
    	char		ModelValue[ARRAY_LENGTH][51];	
    	long  	        RatingScoreSeq[ARRAY_LENGTH];
    	long		RequestNumber[ARRAY_LENGTH];
    } DataToInsert;
    Et le probl�me que j'ai est que si je change ARRAY_LENGTH et que je met cela � 1000, cela me fait une segmentation fault alors qu'a 100 ou m�me 200 comme indiqu�, tout se passe bien.

    Une raison � cela?

    Merci beaucoup de votre aide et de votre temps,
    Albin.

    ps : j'ai pas forc�ment besoin d'utiliser une taille de 1000 mais j'aime pas laisser ce genre de question en suspens...

  2. #2
    Expert confirm�
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (�le de France)

    Informations professionnelles :
    Activit� : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par d�faut
    Avec le peu d'informations que tu communiques (valeur de CODE_LENGTH ? mode de cr�ation des variables DataToInsert ? code qui fait planter ?...), la seule chose qu'on puisse dire est que la taille de la structure est peut �tre alors trop grande pour �tre cr��e en allocation automatique (variable locale sur la pile).

  3. #3
    Membre averti
    Homme Profil pro
    Inscrit en
    Novembre 2011
    Messages
    25
    D�tails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Novembre 2011
    Messages : 25
    Par d�faut
    Comme j'ai dit, le probl�me vient de la taille de ARRAY_LENGTH qui devient trop grande.

    La valeur de CODE_LENGTH est de 10. Et comme j'ai dit aussi, la struct est remplie par un curseur de PRO*C :

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
     
    	EXEC SQL CONTEXT USE :*ctx;
     
    	/* On déclare un curseur */
     
    	EXEC SQL WHENEVER SQLERROR DO OracleDBError();
    	EXEC SQL WHENEVER NOT FOUND DO break;
    	EXEC SQL DECLARE RatingScore_Curs CURSOR FOR
    		SELECT 	person_idn,
    						rating_model,
    						model_var,
    						model_value,
    						rating_score_seq,
    						request_number
    		FROM   		rating_score
    		ORDER BY person_idn,
    						rating_model,
    						model_var;
     
    	EXEC SQL OPEN RatingScore_Curs;
     
    	if (sqlca.sqlcode != 0)
    	{
    		printf("Error openning RatingScore_Curs - SqlCode : %d\n", sqlca.sqlcode);
    		return (void *) -1;
    	}
     
    	/* On ouvre le curseur et on fetch continuellement dans une struc d'array (DataToInsert) représentant une ligne. */
     
    	for(;;)
    	{
     
    		/* Structures de données utilisées pour le fetch :
     
    				-selectedData : les données récupérées.
    				-indicatorData : indicateur sur chaque champs permettant de savoir si la valeur retournée était NULL ou non (utilisé pour éviter une
    				ORA-1455).
    		*/
     
    		DataToInsert selectedData;
    		DataIndicator indicatorData;
     
    		EXEC SQL FETCH RatingScore_Curs INTO :selectedData:indicatorData;
     
    		 if (sqlca.sqlcode != 0)
    		{
    			printf("Error fetching RatingScore_Curs - SqlCode : %d\n", sqlca.sqlcode);
    			return (void *) -1;
    		}
    	}
    Et c'est ce bout de code qui plante (le seul � utiliser la struct pour le moment). Oui je me doutais que la valeur devait �tre trop grande mais m�me si c'est une struct de 6 tableaux, 6 tableaux de taille 1000 c'est quand m�me minuscule compar� � certain programme non? J'ai d�j� trait� des matrice bien plus gigantesque sans avoir aucune segmentation fault...

    Merci,
    Albin.

  4. #4
    Membre �m�rite
    Avatar de Elijha
    Homme Profil pro
    Ing�nieur d�veloppement mat�riel �lectronique
    Inscrit en
    Avril 2003
    Messages
    314
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 56
    Localisation : France, Alpes Maritimes (Provence Alpes C�te d'Azur)

    Informations professionnelles :
    Activit� : Ing�nieur d�veloppement mat�riel �lectronique
    Secteur : B�timent Travaux Publics

    Informations forums :
    Inscription : Avril 2003
    Messages : 314
    Par d�faut
    Bonjour,

    Si je me rappel bien de mes cours de C, les variables globales sont stock�es sur le tas. Pour un programme C, le tas est limit� � 65536 octets. Si l'on prend la taille de ta structure en octets (avec un long � 4 octets par exemple, car cela peu changer d'une machine � une autre) on obtient :
    taille = (1000�4)+(1000�10x1)+(1000�10x1)+(1000�51x1)+(1000�4)+(1000�4) = 83000 octets
    Donc il te manque environs 17ko.

    Dans ce cas, il te reste plus que la solution de l'allocation dynamique de m�moire de ton tableau (malloc() et free()) qui te permettra d'utiliser beaucoup plus de m�moires.

    A toi de jouer et bonne continuation.

  5. #5
    Expert confirm�
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (�le de France)

    Informations professionnelles :
    Activit� : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par d�faut
    Si je me rappel bien de mes cours de C, les variables globales sont stock�es sur le tas
    Non. Elles sont stock�es en g�n�ral dans une zone "programme". Les allocations sur le tas sont obtenues par allocation dynamique.
    Pour un programme C, le tas est limit� � 65536 octets.
    Tu confonds avec la pile utilis�e par les variables en allocation automatique et qui est beaucoup plus limit�e en taille que le tas (mais 65536 est bien peu)

    Les "grosses" variables doivent donc �tre cr��es en global ou par allocation dynamique.

  6. #6
    Membre averti
    Homme Profil pro
    Inscrit en
    Novembre 2011
    Messages
    25
    D�tails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Novembre 2011
    Messages : 25
    Par d�faut
    Ce qui signifie que je dois soit cr�er ma struct en utilisant malloc/free ou alors la d�clarer en globale donc... mais comment faire?

    Comme j'ai apprit la programmation en JAVA j'ai quelques souci avec les fa�ons de faire plus bas niveau. Par exemple, comme je fais pour d�clarer une struct avec des tailles de tableau dynamique?

    Par exemple en voulant cr�er une struct ayant 6tableaux de taille 10 et une autre avec des tableaux de taille 20? Je dois cr�er les tableaux et les donner � la truc � l'aide de pointeur ? Ou y'a il un moyen de le faire � l'int�rieur m�me de la struct?

    Merci infiniment,
    Albin.

  7. #7
    Membre �m�rite
    Avatar de Elijha
    Homme Profil pro
    Ing�nieur d�veloppement mat�riel �lectronique
    Inscrit en
    Avril 2003
    Messages
    314
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 56
    Localisation : France, Alpes Maritimes (Provence Alpes C�te d'Azur)

    Informations professionnelles :
    Activit� : Ing�nieur d�veloppement mat�riel �lectronique
    Secteur : B�timent Travaux Publics

    Informations forums :
    Inscription : Avril 2003
    Messages : 314
    Par d�faut
    Si je me rappel bien de mes cours de C, les variables globales sont stock�es sur le tas
    mea culpa. C'est triste la vieillesse.

    Apr�s quelques recherches (sur architecture x86) :
    • Segment de texte : code
    • Segment de donn�es : variables statiques et globales
    • Segment bss : variables non initialis�es
    • Segment de tas : variables allou�es dynamiquement
    • Segment de pile : variables, appels de fonctions etc.

    [A v�rifier] La taille maximum en allocation serai limit�e � SIZE_MAX qui d�pend de la machine (size_t). Pour une machine 32 bits, cela serait 4294967295 octets.


    En C l'allocation dynamique est tr�s simple, mais il faut absolument v�rifier l'�tat des pointeurs au retour des fonctions d'allocation et faire tr�s attention lors de l'utilisation, car en C il n'y a pas contr�le. Tu peux facilement te retrouver � �crire dans une zone m�moire qui n'appartient pas au programme.
    Dans ton cas, il te faut d�clarer une structure de pointeurs, puis attribuer ces pointeurs en fonction de la taille voulue
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    // Déclarations
    typedef struct
    {
        long    *PersonIdn ;
        char    *RatingModel ;
        char    *ModelVar ;
        char    *ModelValue ;	
        long    *RatingScoreSeq ;
        long    *RequestNumber;
    } DataToInsert ;
     
    DataToInsert table ;
     
    // Allocations
    table.PersonIdn = malloc(ARRAY_LENGTH * sizeof(long)) ;
    if(table.PersonIdn==NULL) {
        printf("Erreur d'allocation sur PersonIdn.\n") ;
        return -1 ;
    }
     
    table.RatingModel = malloc(ARRAY_LENGTH * CODE_LENGTH * sizeof(char)) ;
    if(table.RatingModel==NULL) {
        printf("Erreur d'allocation sur RatingModel.\n") ;
        free(table.PersonIdn) ;  // Libération avant la sortie
        return -1 ;
    }
     
    // etc...
    A la fin de ton programme, il faut lib�rer toute la m�moire qui a �t� pr�c�demment allou�e (fonction free).

    Bonne continuation.

  8. #8
    Membre chevronn� Avatar de themadmax
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    446
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 446
    Par d�faut
    [A v�rifier] La taille maximum en allocation serai limit�e � SIZE_MAX qui d�pend de la machine (size_t). Pour une machine 32 bits, cela serait 4294967295 octets.
    En th�orie sur une machine x86, mais ce chiffre est bien plus faible il est limit� par la m�moire physique et celle affect� au programme par l'OS, qui s'en garde une peu pour lui et les autres programmes programme.
    Tu peux facilement te retrouver � �crire dans une zone m�moire qui n'appartient pas au programme.
    Pour �tre un peu tatillon si ton OS est r�cent il est impossible de sortir de sa zone m�moire une exception sera lev� avant. Mais en tout cas le r�sultat est le m�me il ne faut pas d�pass� la taille allou�.

  9. #9
    Expert confirm�
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (�le de France)

    Informations professionnelles :
    Activit� : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par d�faut
    @Elijha :
    Dans ton cas, il te faut d�clarer une structure de pointeurs, puis attribuer ces pointeurs en fonction de la taille voulue...
    Cette complication est inutile.

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    typedef struct
    {
    	long		PersonIdn[ARRAY_LENGTH];
    	char 		RatingModel[ARRAY_LENGTH][CODE_LENGTH];
    	char		ModelVar[ARRAY_LENGTH][CODE_LENGTH];
    	char		ModelValue[ARRAY_LENGTH][51];	
    	long  	        RatingScoreSeq[ARRAY_LENGTH];
    	long		RequestNumber[ARRAY_LENGTH];
    } DataToInsert; 
     
    // ----en globale
    DataToInsert table ;
    // ----ou en allocation dynamique :
    DataToInsert *table = malloc(sizeof *table) ;
    ....
    free(table);

  10. #10
    Membre averti
    Homme Profil pro
    Inscrit en
    Novembre 2011
    Messages
    25
    D�tails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Novembre 2011
    Messages : 25
    Par d�faut
    Un grand merci � vous deux, je me sens d�j� un peu plus � l'aise quand je joue avec les pointeurs et allocations dynamique !

    Albin.

+ R�pondre � la discussion
Cette discussion est r�solue.

Discussions similaires

  1. Segmentation Fault: struct in_addr
    Par garn_le_troisieme dans le forum C++
    R�ponses: 5
    Dernier message: 08/06/2012, 09h40
  2. [SDL_Image] Img_Load : segmentation fault ....
    Par Mathieu.J dans le forum OpenGL
    R�ponses: 6
    Dernier message: 19/10/2004, 23h52
  3. [REDHAT] Segmentation fault systematique
    Par mela dans le forum RedHat / CentOS / Fedora
    R�ponses: 2
    Dernier message: 21/09/2004, 06h05
  4. R�ponses: 13
    Dernier message: 13/07/2004, 15h41
  5. Comment contrer la "segmentation fault" ?
    Par guillaume_pfr dans le forum C
    R�ponses: 15
    Dernier message: 08/08/2003, 13h43

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo