Accueil > Forum > > > > Gestion dynamique de la mémoire
Gestion dynamique de la mémoire
vendredi 26 février 2010 à 10:22:14 |
Gestion dynamique de la mémoire

totolfpn
|
Bonjour, j'apprends le C en autodidacte et je bloque sur strcmp et les pointeurs. Mon code marche bien sans pointeur, mais il y a un truc qui m'échappe des que je rajoute l'*'.Quand à accéder au tableau dans REP, je ne sais pas comment faire. Pouvez-vous m'aider? Merci d'avance
struct REP
{
char nom[21];
int nbtel;
int TNUM[3];
};
void main()
{
REP *TAB[30];
int ind=0;
int i;
char nomlu[21];
printf("Entrez le nom :");
gets(nomlu);
while(nomlu[0]!='*')
{
for(i=0; i<=ind && (strcmp(nomlu, TAB[i]->nom)!=0); i++);
{
if(i>ind)
{
strcpy(TAB[ind]->nom, nomlu);
printf("ENREGISTREMENT EFFECTUER %s\n", TAB[ind]->nom);
ind+=1;
}
else
printf("NOM DEJA ENREGISTRE\n");
}
printf("Entrez le nom :");
gets(nomlu);
}
system ("pause");
}
|
|
vendredi 26 février 2010 à 10:59:45 |
Re : Gestion dynamique de la mémoire

CptPingu
|
Tu dois allouer de la mémoire, tout simplement, ce n'est pas automatique. Ou alors tu retires l'étoile qui n'est pas très utile ici.
Voici un cours sur les pointeurs:
http://0217021.free.fr/Cours/pointeurs.pdf
Une petite lecture de celui-ci te permettra, je pense, de comprendre ton erreur et de la corriger :)
_____________________________________________
Historique de mes créations, et quelques articles:
http://0217021.free.fr/portfolio
|
|
vendredi 26 février 2010 à 12:51:47 |
Re : Gestion dynamique de la mémoire

goodboy21
|
Bonjour, il est vrai que la notion de pointeur est très abstraite, je te fais un bref descriptif, pour faire simple nous mettrons de coté, Allocation sur la pile et sur le tas, système 32-bit et 64-bit et pour finir alignement.
Que contient réellement une variable?
-une variable contient l'emplacement mémoire du premier octet représentant la donnée.
Par Exemple.
pour une variable "int val" situé à l'adresse mémoire 0x632A1 par exemple.
Si tu fais val=5, c'est la zone mémoire partant de 0x632A1 à 0x632A4 représentant 4 octets (taille d'un entier) qui sera affectée.
dans le cas de ta structure "REP", si on a une variable "REP MyRep" qui obtient l'adresse 0xCF650 par exemple pendant l'exécution et que tu fais
MyRep.nbTel=12. on prendrait l'adresse de base à savoir 0xCF650 auquel on rajoute 21 pour passer la zone représentant "nom",on affecterait alors la zone allant de 0xCF665 à 0xCF669.(fais pas trop attention au emplacement qui sont noté en hexadécimal)
- C'est quoi un pointeur?
c'est tout simplement une variable qui sert à stocker des adresses mémoire, pour information sur un système 32-bit, un pointeur occupe une zone mémoire de 4octects tout comme un entier, tu verras par la suite que tu peux aussi stocker des adresses mémoires dans un entier non-signé et utilisé des Cast afin de manipuler la donnée qu'il contient.
Par Exemple
j'ai une variable "int *val", jusqu'ici "val" n'est pas très différent du "val" de tout à l'heure, admettons que val se trouve à l'adresse 0xED004, il s'étale de la zone 0xED004 à 0xED008 puisqu'un pointeur ou du moins une adresse est contenu sur 4 octets, Sauf que la zone du val plus haut contenait 5; et celui-ci doit contenir une valeur représentant l'adresse mémoire d'un entier, mais lequel?
soit on place dans val une adresse mémoire existante, soit il nous faut en créer un nouveau. On décide d'en créer un nouveau avec l'opérateur new ;val= new int, met dans val la valeur de l'emplacement nouvellement créer soit 0X33AAC par exemple.
pour affecter une valeur à val on fait un déférencement soit *val=45; et en quoi consiste-il? il s'agit d'aller à l'emplacement de val soit 0xED004, de lire la valeur qu'il y a à cet emplacement c'est à dire 0X33AAC, d'aller à l'adresse 0X33AAC et de finalement écrire notre valeur.
Pour schématiser on pourrait dire qu'un pointeur est une variable qui contient l'emplacement mémoire d'une autre variable.
Pour finir:
-Toutes variables déclarées dans une fonction est créée dans la pile, même le val de notre "int *val" est créé dans la pile, c'est la valeur de l'emplacement qu'il contient qui doit être valide ou bien alloué par le programmeur, si on essaye d'écrire dans une zone non-alloué c'est le plantage assuré.
Pourquoi passer par les pointeur puisqu'il s'agit d'une variable tampon?
- parce qu'à la fin d'une fonction toutes les variables créées sur la pile sont détruites, et pour gérer des données en mémoires mm à la fin des fonctions il faut passer par la création d'éléments dans le tas, et pour ce faire on est obligé de passer par les pointeurs.
Ceci ne répond pas à ton problème mais peut t'aider à sa résolution.
pour te donner un coup de pouce, tu déclares un tableau de 30 pointeurs, mais ces dernier doivent contenir des emplacements mémoires invalides.
Surtout n'oublies pas de détruire tout allocation initié par new.
Au départ les pointeurs ne sont pas évident, mais après c'est le fun.
Salut, En espérant t'avoir aider.
|
|
vendredi 26 février 2010 à 14:33:30 |
Re : Gestion dynamique de la mémoire

totolfpn
|
Merci pour vos réponses express, j'ai rajouté
TAB[ind]=(REP*)malloc(sizeof(REP));
avant strcmp et ça marche!! Après j'ai transformé "nom" en "*nom" dans ma struct et la ça ne marche plus du nouveau, pourtant j'ai mis
TAB[ind]->nom=strdup(nomlu);
a la place de strcpy. Il me sembait pourtant d'avoir compris avec vos explications.
J'ai cherché new dans la bible C, c'est pas plutôt du c++?
Merci d'avance
|
|
vendredi 26 février 2010 à 14:56:00 |
Re : Gestion dynamique de la mémoire

goodboy21
|
oui en effet new c'est avec le C++; tu remplaces "char nom[21]" par "char *nom" tu rencontres le mm problème car tu n'as pas alloué l'espace mémoire pour ton "nom". avec "char nom[21]" ta structure à une taille de 37 octets soit: 21 pour "nom", 4 pour nbtel et 12=4*3 pour TNUM( on ne prend pas en compte l'alignement) Alors qu'avec "char*nom" la taille est : 20 soit 4 pour nom, 4 pour nbtel et 12 pour TNUM. soit tu alloues de la mémoire dont tu mets l'adresse dans "nom" ou soit tu laisses la première version dans laquelle l'espace pour représenter ton nom y est déjà.
Prends le temps de comprendre les pointeurs, car tu y gagneras beaucoup par la suite, à cause des erreurs à la con qu'on commet des fois.
|
|
vendredi 26 février 2010 à 14:59:44 |
Re : Gestion dynamique de la mémoire

CptPingu
|
Envoie nous ton code complet qu'on puisse voir où est l'erreur.
TAB[ind]->nom=strdup(nomlu);
@goodboy21: strdup fait l'allocation, donc son problème ne vient pas de là.
_____________________________________________
Historique de mes créations, et quelques articles:
http://0217021.free.fr/portfolio
|
|
vendredi 26 février 2010 à 15:23:07 |
Re : Gestion dynamique de la mémoire

totolfpn
|
Voici le code complet:
#include "stdio.h"
#include "stdafx.h"
#include "stdlib.h"
#include "string.h"
struct REP
{
char *nom;
int nbtel;
int TNUM[3];
};
void main()
{
REP *TAB[30];
int ind=0;
int i;
char nomlu[21];
printf("Entrez le nom :");
gets(nomlu);
while(nomlu[0]!='*')
{
TAB[ind]=(REP*)malloc(sizeof(REP));
for(i=0; i<=ind && (strcmp(nomlu, TAB[i]->nom)!=0); i++);
{
if(i>ind)
{
TAB[ind]->nom=strdup(nomlu);
printf("ENREGISTREMENT EFFECTUER %s\n", TAB[ind]->nom);
ind+=1;
}
else
printf("NOM DEJA ENREGISTRE\n");
}
printf("Entrez le nom :");
gets(nomlu);
}
system ("pause");
}
Pas de message d'erreur a la compilation mais a l'execution ça bloque sur la ligne strcmp:
- str1 0xcdcdcdcd <Ptr> incorrect unsigned char *
CXX0030: Erreur : impossible d'évaluer l'expression
- str2 0x0a09f9d4 <Ptr> incorrect unsigned char *
CXX0030: Erreur : impossible d'évaluer l'expression
Toujour un probleme d'allocation, je suis dessus depuis ce matin!
Merci pour vos reponses
|
|
vendredi 26 février 2010 à 15:53:41 |
Re : Gestion dynamique de la mémoire

CptPingu
|
Plein de petite erreurs:
- ind n'est pas initialisé, donc vaut "aléatoire", et donc tu accèdes à une case invalide.
- Tu utilises sûrement un compilateur C++, parce que ce n'est pas une syntaxe rigoureuse du C (le struct que tu ne précise pas, et le fait de caster ton malloc, ce qui ne devrait pas être obligatoire). Attention C != C++, et tu ne peux pas compiler correctement du C "pure" avec un compilateur C++.
- system est à éviter (sauf system("pause") en débug seulement, qui peut être utile à quelqu'un sous Windows) car il pose des problèmes de compabilité (par exemple, je suis sous Linux et system("pause") ne fonctionnera pas chez moi).
- gets est déprécié. A éviter donc.
- stdafx.h => Pour quoi faire ?
Voici une correction. J'ai ajouter des fonctions pour rendre le code plus modulable et plus clair:
Code C/C++ :
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define REP_SIZE 30
typedef struct
{
char* nom;
int nbtel;
int tnum[3];
} Rep;
int exists(Rep* tab[REP_SIZE], const char* name)
{
int i = 0;
while (tab[i] != NULL && i < REP_SIZE)
{
if (strcmp(name, tab[i]->nom) == 0)
return 1;
++i;
}
return 0;
}
int addRecord(Rep* tab[REP_SIZE], const char* name)
{
int i = 0;
/*
** On recherche la premiere position libre
*/
while (tab[i] != NULL && i < REP_SIZE)
++i;
if (i >= REP_SIZE)
return 0;
tab[i] = malloc(1 * sizeof(Rep));
tab[i]->nom = strdup(name);
return 1;
}
void displayTab(Rep* tab[REP_SIZE])
{
int i = 0;
for (i = 0; tab[i] != NULL && i < REP_SIZE; ++i)
printf("%s ", tab[i]->nom);
printf("\n");
}
void freeTab(Rep* tab[REP_SIZE])
{
int i = 0;
for (i = 0; tab[i] != NULL && i < REP_SIZE; ++i)
{
free(tab[i]->nom);
free(tab[i]);
}
printf("\n");
}
int main(void)
{
char nomlu[21] = {0};
Rep* tab[REP_SIZE] = {0};
int i = 0;
while (nomlu[0] != '*')
{
printf("Entrez le nom :");
scanf("%s", nomlu);
if (nomlu[0] == '*')
break;
if (exists(tab, nomlu))
printf("NOM DEJA ENREGISTRE\n");
else
{
if (addRecord(tab, nomlu))
printf("ENREGISTREMENT EFFECTUE %s\n", tab[i]->nom);
else
printf("ENREGISTREMENT RATE %s\n", nomlu);
}
}
displayTab(tab);
freeTab(tab);
return 0;
}
_____________________________________________
Historique de mes créations, et quelques articles:
http://0217021.free.fr/portfolio
|
|
vendredi 26 février 2010 à 16:57:38 |
Re : Gestion dynamique de la mémoire

totolfpn
|
Ups, mon code m'a l'air tout minable d'un coup!
En effet, j'ai Visual Studio 2008 et "system" est la pour que je vois l'état de mes variables à la fin de l'exécution, stdafx est la par erreur. J'ai mis ind=0, il faut faire autrement pour l'initialiser? Pour gets je me renseigne, en tout cas maintenant j'ai le week-end pour assimiler la "correction"!! J'ai du boulot, dommage que j'ai la tete dur…
En tout cas merci pour vos réponses, c'est sympa
|
|
vendredi 26 février 2010 à 17:02:55 |
Re : Gestion dynamique de la mémoire

CptPingu
|
Réponse acceptée !
ind était bien initialisé, c'était une erreur de copier-coller de ma part :)
system est utile est en debug, pas de souci.
_____________________________________________
Historique de mes créations, et quelques articles:
http://0217021.free.fr/portfolio
|
|
Cette discussion est classée dans : int, printf, rep, ind, nomlu
Répondre à ce message
Sujets en rapport avec ce message
Trier une structure indexée [ par RootASM ]
Bonjour,J'ai écrit un programme qui permet de faire des recherches, ajout, suppression sur une liste de membres.Je dois trier cette liste de nom, lors
Langage C : printf et int_least64_t [ par SesechXP ]
Salut !J'ai un problème pour afficher des variables de type int_least64_t à l'aide de printf. Voici la ligne de code concernée :printf("%lld
Quel est le bug ? [ par mayapour ]
Bonjour, En testant ce petit programme qui est l'équivalent du ls sous linux avec différentes options, je me suis appercu qu'il affiche un . (point) e
Lecture et ecriture sur fichier [ par developvbdebut ]
Bonjour tout le mondeJe travaille sur la gestion des fichier en c.Mon livre n'explique pas clairement l'ectriture et la lecture dans les fichiers.Voic
calendrier [ par chinois57 ]
bjr tt le monde mon prof de math ma demander de faire un calendier perpituel en C mais je coince un peu bcp "please help me" ma source est :#include #
fonctions sur les tableau [ par micoo86 ]
Bonjour,en faite j'ai fait un programme avec le tableau (somme,affichage,minimum,maximum)mais j'arrive pas a faire le rest de l'exercice.si quelqu'un
Problèmes tableaux [ par Squallgamer ]
Voila j'ai un exo en C et j'ai un peu de mal a faire les deux dernières question. J'ai beau cherché je vois pas trop la solution, je fais donc apelle
programmation en C [ par badramus ]
Bonjour voici le programme que j'ai pu faire mais ça ne marche comme je le souhaite. veuillez m'aidez a reoudre ce problème.voici le programme
Windows plante {je sais pas nouveau } pour l'execution du mon code [ par darkwhite ]
Salut a tous Je debute en C, et j'ai commencer a faire un petit programme. A la moitié de la creation je l'essaie mé windows me sort un message derreu
affichage bizarre [ par darkwhite ]
Salut a tousJe commence par faire une lotterie simple mais j'ai un probleme au niveau de l'affichage d'un tableau, mon code est le suivant#include #in
Livres en rapport
|
Derniers Blogs
JOYEUX ANNIVERSAIRE NIXJOYEUX ANNIVERSAIRE NIX par ebartsoft
Souhaitons un bon et joyeux anniversaire à notre hôte à tous, Nix.
Je ne le répéterais jamais assez mais sans lui rien ne serait possible. Il défit en permanence les lois de la gravité et comme il le dit si bien, si tu lui fais confiance ça devra...
Cliquez pour lire la suite de l'article par ebartsoft IMAGINE CUP 2012, MAKE A SIGN EN FINALEIMAGINE CUP 2012, MAKE A SIGN EN FINALE par junarnoalg
Voilà qui est fait, la nouvelle est officielle ! L'équipe belge "Make a Sign" va au pays des kangourous défendre son projet dans la catégorie Software Design. http://www.imaginecup.com/CompetitionsContent/Competition/WorldwideFinalists.aspx V...
Cliquez pour lire la suite de l'article par junarnoalg KINECT 1.5 IS OUT !KINECT 1.5 IS OUT ! par Vko
La version 1.5 du Kinect For Microsoft vient tout juste de sortir ! Plein de nouveautés: Tracking de squelette en Near Mode Détection en position assise Détection faciale avec un SDK dédié Documentation et des guideline (enfin) Un out...
Cliquez pour lire la suite de l'article par Vko LES ACTUALITéS DE LA SEMAINE SUR C2I.FR (14 MAI - 20 MAI) LES ACTUALITéS DE LA SEMAINE SUR C2I.FR (14 MAI - 20 MAI) par richardc
Mise à jour des Web API du 14 Mai
Réservez dès maintenant votre journée du 20 juin pour le Windows Azure Dev Camp 2012 à Paris
Mise à jour de Team Foundation Service
MechCommander 2 sur Windows 8
Entity Framework 5 Release Candidate e...
Cliquez pour lire la suite de l'article par richardc REACTIVE EXTENSIONS : CONSOMMER DES SERVICES AVEC RX PARTIE 3, LES PIèGES à éVITERREACTIVE EXTENSIONS : CONSOMMER DES SERVICES AVEC RX PARTIE 3, LES PIèGES à éVITER par Groc
Une mauvaise utilisation de rx lors de l'écriture d'une couche d'accès à des services peut conduire à des cas embarassants avec des erreurs mal gérées, des appels qui ne partent lorsqu'ils le devraient, et même des résultats incorrects . le tout nuis...
Cliquez pour lire la suite de l'article par Groc
Logiciels
sDEVIS-FACTURES vlPRO (8.1.0.3)SDEVIS-FACTURES VLPRO (8.1.0.3)sDEVIS-FACTURES vlPRO a été mis au point pour les particuliers, créateurs, entrepreneurs, artisa... Cliquez pour télécharger sDEVIS-FACTURES vlPRO 974 Application Server (12.2.4.6)974 APPLICATION SERVER (12.2.4.6)Développez de puissantes applications dans un environnement de 'cloud computing', clusterisé, séc... Cliquez pour télécharger 974 Application Server vPicture (1.4.2.1)VPICTURE (1.4.2.1)Avec vPicture, hébergez vos images facilement et rapidement.
vPicture est un utilitaire simple, ... Cliquez pour télécharger vPicture Easy-Planning (2.2.1.6)EASY-PLANNING (2.2.1.6)Easy-Planning permet de créer des plannings sous la représentation de diagrammes et est adapté au... Cliquez pour télécharger Easy-Planning COM-BACKUP (2.0)COM-BACKUP (2.0)
COM-BACKUP est un logiciel de sauvegarde qui permet de planifier les sauvegardes de vos dossiers ...
Cliquez pour télécharger COM-BACKUP
|