Pb d'allocation memoire en C pas résolu

Résolu
Utilisateur anonyme -  
 Utilisateur anonyme -
salut,
voilà maintenant que je suis désespéré je vous envoit en espérant que quelqu'un m'aidie à résoudre le pb, pour rappeler le pb c'est lors de l'allocation memoire en C avec calloc il retourne NULL ce qui veut dire plus d'espace memoire à allouer

je travaille avec les arbre n-aire et voici un petit morceau du prog :

struct Noeud{ //liste des message
char content[201];
struct Cellule * response;
};
typedef Noeud* Message;

struct Cellule{ //arbre n-aire de reponse
struct Noeud* message;
struct Cellule* next;
};
typedef Cellule* Response;

void main(){
.
.
.
//pas de pb ic, le prog continuie et R != NULL

R->intro = create_response(buffer);

//a partir d'ici R = NULL et le prog s'arrete avec un message d'erreur:
//Exception non gérée à 0x00f42c60 dans forum.exe : 0xC0000005: Violation d'accès lors de l'écriture à //l'emplacement 0x00000004.

R = create_response(buffer);
R->next = M->response;
.
.
.

}

Response create_response(char *s){
Response R;
Message M;
//un message contient une liste de reponse
//et une reponse contient un message
//
//alloction d'un espace pour la reponse
if( R = (Response)calloc(1,sizeof(Response))){ //le pb apparait ici et R = NULL

//allocation d'un espace pour le message
if( M = (Message)calloc(1,sizeof(Message))){
strncpy(M->content,s+49,200); M->content[200]='\0';
}else{
puts("memoire insuffisante");
return NULL;
}
.
.
}else{
puts("memoire insuffisante");
return NULL;
}
return R;
}

j'espère que vous m'aidiez et merci d'avance
A voir également:

22 réponses

Utilisateur anonyme
 
svp aidez moin ;(
0
fiddy Messages postés 11069 Date d'inscription   Statut Contributeur Dernière intervention   1 845
 
Salut,
Attention, même si c'est souvent le cas, une allocation échoue ce n'est pas forcément un problème de manque de mémoire.
Ensuite, il y a plusieurs erreurs :
Tu as oublié le mot-clé struct dans ton typedef. La bonne syntaxe est : typedef struct Noeud* Message;

main() renvoie un int. Donc son prototype est int main(void) si tu ne veux pas d'arguments, et il retourne 0 (return 0;) si tout va bien.

Cdlt
0
Utilisateur anonyme
 
c'est vrai à propos de struct mais malheureusemen ça n'a pas résolu le problème j'aurai aimé que ça soit la source d'erreur mais R est toujours NULL
0
fiddy Messages postés 11069 Date d'inscription   Statut Contributeur Dernière intervention   1 845
 
Il y a forcément une erreur quelque part. Pourrais-tu poster un code fonctionnel reproduisant ton erreur (donc en enlevant tout ce qui est inutile) en l'incluant entre deux balises code (à droite de souligner). Ca sera plus simple pour voir l'origine de l'erreur.
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Utilisateur anonyme
 
j'ai pas bien saisie ce que vous voulez dire par un code fonctionnel, je vous ai envoyé la partie du code qui contient l'erreur, ce n'est pas ça ce dont vous avez besoin ?
0
Utilisateur anonyme
 
je vais voir ce que je peut faire..
0
Utilisateur anonyme
 
bon voila ce que j'ai pu faire j'espère que vous m'aider enfin
ressources creer: fichier message.txt contenant quelque ligne (2 ou 3) de texte et voici le code
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>	
#include <conio.h>

struct Noeud{	//liste des message
	char content[201];
	struct Cellule * response;
};
typedef struct Noeud* Message;

struct Cellule{		//arbre n-aire de reponse
	struct Noeud* message;
	struct Cellule* next;
};
typedef struct Cellule* Response;

Response create_response(char *s){
	Response R;
	Message M;
		//alloction d'un espace pour la reponse
		if( R = (Response)calloc(1,sizeof(Response))){
			//allocation d'un espace pour le message
			if( M = (Message)calloc(1,sizeof(Message))){
				strncpy(M->content,s,200); M->content[200]='\0';
				M->response = NULL;
			}else{
				puts("memoire insuffisante");
				return NULL;
			}
			//faire le lien entre la reponse et le message
			R->message = M;
			R->next = NULL;
		}else{
			puts("memoire insuffisante");
			return NULL;
		}
		return R;
}


void main (){
	FILE *in;
	in = fopen("message.txt","r");
	char buffer[256];
	Response R = NULL;
	Message M = NULL;
	if(in){
		while(fgets(buffer,256,in)){
			R = create_response(buffer);
		}
	}else{
		perror("Erreur: ");
	}
	fclose(in);
}

0
Utilisateur anonyme
 
alors ?
0
fiddy Messages postés 11069 Date d'inscription   Statut Contributeur Dernière intervention   1 845
 
Salut,
Je t'ai corrigé deux trois trucs. En tout cas sur ma machine, j'ai testé ton code et je n'ai aucune erreur segmentation sauf dans le cas où message.txt n'existe pas.

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

struct Noeud{	//liste des message
    char content[201];
    struct Cellule * response;
};
typedef struct Noeud* Message;

struct Cellule{		//arbre n-aire de reponse
    struct Noeud* message;
    struct Cellule* next;
};
typedef struct Cellule* Response;

Response create_response(char *s){
    Response R;
    Message M;
    //alloction d'un espace pour la reponse
    if( (R = (Response)calloc(1,sizeof(Response)))){
        //allocation d'un espace pour le message
        if( (M = (Message)calloc(1,sizeof(Message)))){
            strncpy(M->content,s,200); M->content[200]='\0';
            M->response = NULL;
        }else{
            puts("memoire insuffisante");
            return NULL;
        }
        //faire le lien entre la reponse et le message
        R->message = M;
        R->next = NULL;
    }else{
        puts("memoire insuffisante");
        return NULL;
    }
    return R;
}


int main (void){
    FILE *in;
    in = fopen("message.txt","r");
    char buffer[256];
    Response R = NULL;
    Message M = NULL;
    if(in){
        while(fgets(buffer,256,in)){
            R = create_response(buffer);
        }
    }else{
        perror("Erreur: ");
    }
    fclose(in);
    free(R);
    free(M);
    return 0;
}
0
Utilisateur anonyme
 
t'a essayé avec 2 ou trois ligne de texte? comme ceci par exmple :
premier texte
deuxieme texte
troixième texte
0
fiddy Messages postés 11069 Date d'inscription   Statut Contributeur Dernière intervention   1 845
 
Oui, même avec quatre lignes ^^.
0
Utilisateur anonyme
 
j'ai essayé le tien, c'est le meme pb encore
0
Utilisateur anonyme
 
non non dit pas ça st'plai , mais qu'est ce qu'il a mon ordi ;(
0
Utilisateur anonyme
 
je peut prendre par ta parole que ça marche nickel sans pb? que le pb vient de mon foutu d'ordi ou d'ide?
0
Utilisateur anonyme
 
bon alors merci pour votre aide en tout cas.
0
lami20j Messages postés 21331 Date d'inscription   Statut Modérateur, Contributeur sécurité Dernière intervention   3 569
 
Salut,

Tu compiles avec quoi?
Peut être qu'il faut essayer avec un autre compilateur pour voir.
0
fiddy Messages postés 11069 Date d'inscription   Statut Contributeur Dernière intervention   1 845
 
Oui, c'est vraiment bizarre.
Le code que tu m'as donné marche bien sur ma machine. C'est tout ce que je peux t'assurer ^^.
0
Utilisateur anonyme
 
je compile avec visual Studio 2008, j'ai fait un déboguage pas à pas et a chaque fois le meme résultat R = NULL a partir de la deuxième
0
Mahmah Messages postés 496 Date d'inscription   Statut Membre Dernière intervention   125
 
Bonsoir,

Je n'ai pas d'idée sur le refus du calloc mais je pense qu'un point important est à corriger:

    Response R;

    //alloction d'un espace pour la reponse
    if( (R = (Response)calloc( 1, sizeof( Response ) ) )


R est de type Response soit un Cellule *
Ici la mémoire allouée dans le calloc est de taille 1 * sizeof( Response )
La zone mémoire demandée est donc prévue pour contenir un seul objet de type Response, ce qui correspond à la taille d'un pointeur sur une Cellule. (Soit 4 ou 8 octects selon l'architecture 32 ou 64 bits) Si la zone mémoire contient un Cellule *, alors le résultat du calloc qui est l'adresse de la zone réservée devrait être un Cellule ** (l'adresse d'une zone mémoire pouvant contenir une Cellule *)

Avec un exemple plus simple:
int *p;

p = (int *) calloc( 1, sizeof( int   ) );
// Au lieu de 
p = (int *) calloc( 1, sizeof( int* ) );


Je pense que le code voulu était :
    Response R;

    //alloction d'un espace pour la reponse
    if( (R = (Response) calloc( 1, sizeof( Cellule ) ) )

Cela peut produire un erreur dans le programme mais normalement pas dans l'allocation elle-même.

Même chose pour le Message M.

Je regarde si ça marche chez moi,
M.
0
Mahmah Messages postés 496 Date d'inscription   Statut Membre Dernière intervention   125
 
J'ai testé le code posté par Fiddy

Je confirme mon précédent post : La taille allouée dans les calloc n'est pas correct et produit des dépassements.

Le code a été compilé sous Visual 2003, les allocations mémoires sont effectuées sans erreur pour les deux premières. (R et M) Lors du deuxième appel à la fonction create, le premier calloc renvoie NULL chez moi aussi.

En corrigeant les tailles allouées (respectivement sizeof( Cellule ) et sizeof( Noeud ) ) évitant ainsi les dépassements, calloc se sent mieux et n'échoue plus lors des appels au create sur un fichier de test de 5 lignes.

Bien à vous,
M.

PS:
Effectivement le fclose est mal placé puisqu'il ferme le fichier même si le test du dessus trouve qu'il n'a pas été ouvert.
0