Pb d'allocation memoire en C pas résolu

Résolu/Fermé
Utilisateur anonyme - 16 janv. 2009 à 20:05
 Utilisateur anonyme - 17 janv. 2009 à 11:46
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

22 réponses

Utilisateur anonyme
16 janv. 2009 à 20:37
svp aidez moin ;(
0
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 835
16 janv. 2009 à 20:49
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
16 janv. 2009 à 21:00
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 samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 835
16 janv. 2009 à 21:07
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
16 janv. 2009 à 21:16
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
16 janv. 2009 à 21:17
je vais voir ce que je peut faire..
0
Utilisateur anonyme
16 janv. 2009 à 22:42
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
16 janv. 2009 à 22:56
alors ?
0
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 835
16 janv. 2009 à 22:57
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
16 janv. 2009 à 23:01
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 samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 835
16 janv. 2009 à 23:04
Oui, même avec quatre lignes ^^.
0
Utilisateur anonyme
16 janv. 2009 à 23:05
j'ai essayé le tien, c'est le meme pb encore
0
Utilisateur anonyme
16 janv. 2009 à 23:06
non non dit pas ça st'plai , mais qu'est ce qu'il a mon ordi ;(
0
Utilisateur anonyme
16 janv. 2009 à 23:11
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
16 janv. 2009 à 23:14
bon alors merci pour votre aide en tout cas.
0
lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 567
16 janv. 2009 à 23:18
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 samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 835
16 janv. 2009 à 23:18
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
16 janv. 2009 à 23:25
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 lundi 17 septembre 2007 Statut Membre Dernière intervention 22 juin 2010 125
17 janv. 2009 à 01:21
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 lundi 17 septembre 2007 Statut Membre Dernière intervention 22 juin 2010 125
17 janv. 2009 à 01:45
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