Aller au contenu

Trouvez l'erreur ... comment est ce possible????


debuthmx

Messages recommandés

voici un programme qui traite de l'allocation dynamique de memoir.

#include <iostream>

#include <stdlib.h>

using namespace std;

int main(void)

{

int *p;

p=new int;

for (int i=0;i<3;i++) p=i;

for (int i=0;i<3;i++) cout<<" *P = "<<p<<endl;

return 0;

}

Le programme tel qu'il est ecrit ci-dessus devrait me retourne n'importe quoi a l'affiachage. En effet je lui demande de m'allouer de la memoir qu'une seul fois et pour un seul enier. Or juste endessous, j'encode 3 valeur et mieux encore il me les affiche juste apres voici les resultats:

[moimeme@dbs007 Bidon]$ ./Mallnew

*P = 0

*P = 1

*P = 2

Il m'affiche bien les trois valeurs, alors que normalement, chaque nouvelle valeur devrait ecraser l'encienne !!!!

Si vous trouver pourquoi ????

p.s. Je travail sous linux mais le meme resultat est fournis sous windows

Lien vers le commentaire
Partager sur d’autres sites

de toute manière quand tu fais

int *p;

ca ne change rien a la mémoire.

quand tu fais

p=new int;

ça alloue juste un entier. et ça le met à.

mais p désigne en fait *(p+i) càd la valeur située i cases mémoires après *p

a chaque fois que t'en utilise un il l'alloue automatiquement (ainsi que je pense tous ceux d'avant : ex si tu fais p[3] il va allouer (si ce n'est dja fait) p[0] à p[3])

du coup ta première boucle alloue automatiquement les p[0 à 2] qui contiennent alors n'importe kwa

puis tu leur affecte respectivement les valeurs 0 1 2

y'a pas de souci... tout est normal

Lien vers le commentaire
Partager sur d’autres sites

ah ben faudra dire ca a mon gcc alors pcq je crois qu'il est pas au courant... :francais:

en tout cas je me suis jamais soucié de l'allocation sauf avec des tableaux à plus d'une dimension...

et le comportement de ton prog est 100% conforme à ce que j'ai appris cette année en cours de C (mais vraiment de base, les cours, alors y'a surement des tonnes de subtilités que je connais pas encore :p )

Lien vers le commentaire
Partager sur d’autres sites

En fait je ne vois pas ton problème...

Ton code écrit les nombres de 0 à 3 dans 3 adresses mémoire contiguës (mais non allouées, c'est super crade) à partir de l'adresse pointée par P; puis la seconde boucle relit les valeurs de ces 4 zones mémoire.

Si rien ne vient écrire précisément à ces adresses entre le moment où tu écris et le moment où tu relis, il n'y a aucune raison d'obtenir des valeurs autres que celles que tu as écrites...

Fais le test : enlève ta première boucle (qui écrit), et là tu auras effectivement des valeurs aléatoires.

Par contre ce code est crade... Si par pur hasard P est alloué juste avant une zone critique et que tu débordes dedans avec ta boucle d'écriture, ça peut mettre un beau merdier dans ton système... :francais:

Lien vers le commentaire
Partager sur d’autres sites

Comme quoi on devrait toujours apprendre à programmer en Pascal avant de passer au C...

On a eu un plein trimestre sur la gestion des pointeurs en Pascal en prépa, dans lequel on a pu voir les listes chaînées, les arbres, etc. et les mettre en oeuvre de toutes les manièrse possibles. Ensuite, quand on est passés au C, on savait programmer proprement, et personne n'a jamais eu de problème d'allocation mémoire. :francais:

Lien vers le commentaire
Partager sur d’autres sites

Réserver de la mémoire, c'est juste mettre des petits drapeaux autour des zones que l'on va utiliser. Si on veut aller au delà des drapeaux, rien ne nous en empêche.

La preuve est le programme suivant ou je ne fait aucune allocation dynamique du tout:

#include <iostream>

using namespace std;

int main(void)

{

char tab1;

for(int i=0;i<3;i++) *(&tab1+i)='a';

for(int i=3;i<10;i++) *(&tab1+i)='b';

for(int i=0;i<10;i++) cout<<(i+1)<<" "<<tab1<<endl;

return 0;

}

je ne reserve qu'un emplacement memoir de 1 octet pour un seul caractere, mais j'en encode 10 !!! Et a l'affichage, il m'affiche bien les 10 !!!

Lien vers le commentaire
Partager sur d’autres sites

C'est ce que j'explique plus haut. On peut écrire dans des zones non réservées, comme on peut rouler en-dehors des routes et faire du ski hors-piste : ça peut marcher, mais si on provoque un accident faudra pas s'étonner...

Il FAUT réserver la mémoire qu'on utilise. De même, il FAUT la libérer ensuite. Toute autre manière de procéder est à proscrire et démontre l'incompétence du programmeur.

Par ailleurs, dans tous les bouts de code que tu as collés dans ce thread, tu déclares plusieurs fois la variable i (trois "int i" dans les boucles...), et le prototype de ton "main" n'est pas conforme au standard.

Je te conseille d'acheter un bouquin au plus vite...

Lien vers le commentaire
Partager sur d’autres sites

je ne vois pas en quoi mon code n'est pas conforme au standard ??? Ci ce n'est la maniere dont j'utilise la memoir ... mais la c'etait fais expres, je savait depuis le debut que c'etait crade. Et je ne vois pas en quoi ma facon de definir ma fonction main ou mes indice i pose probleme !!!!

Lien vers le commentaire
Partager sur d’autres sites

On ne déclare pas 3 fois une variable au sein d'une même fonction...

D'ailleurs en C (pas C++) les variables doivent être déclarées au tout début de la fonction, avant toute autre instruction.

De plus la fonction main doit prendre comme paramètres argc et argv, indiquant le nombre et les valeurs des paramètres passés au programme.

Je maintiens donc ce que j'ai dit. Achète un bouquin.

Lien vers le commentaire
Partager sur d’autres sites

AAAAAAAAAAAAAAHHHHHHHHHHHHHHHHHHH

AU SECOURS !!!!

Vous êtes des fous !!!

Ce programme n'est pas du tout standard !!!

-"using namespace std;" hum c'est du C ANSI, ça ?

-L'opérateur "new" est un opérateur C++

-Pareil pour "cout<<" .. et autres "<<"

-"p=i;" AAHH utilisation d'un tableau alors qu'il n'y a pas eu d'allocation mémoire pour autant de données ...

EDIT : j'avais pas vu : "for(int i;"... c'est pas possible en C, ça, seulement en C++

Si tu compile avec les option strictes, ça va même pas compiler (à cause du new)

("gcc mallnew.c -ansi -pedantic -W -Werror -Wall -o Mallnew")

Et là, ça écrit n'importe où en mémoire ... donc ça peut faire planter l'OS (entre autres)

En plus, il n'y a pas d'allocation dynamique ...

Si tu veux écrire un prog qui écrase les données :

#include <stdio.h>

int main(void)
{
int p;
int i;
for (i=0;i<3;i++) p=i;
for (i=0;i<3;i++) printf("p=%i\n", p);
return 0;
}

le même code avec de l'allocation dynamique (qui ne sert pas à grand chose) :

#include <stdio.h>
#include <malloc.h>

int main(void)
{
int *p;
int i;
p=(int *)malloc(sizeof(int));
for (i=0;i<3;i++) *p=i;
for (i=0;i<3;i++) printf("*p=%i\n", *p);
free(p);
return 0;
}

Plus d'allocation dynamique (crée 3 places pour les valeurs mais en garde une seule)

(c'est peut-être ça que tu voulais)

#include <stdio.h>
#include <malloc.h>

int main(void)
{
int *p;
int i;
for (i=0;i<3;i++)
{
p=(int *)malloc(sizeof(int));
*p=i;
}
for (i=0;i<3;i++) printf("*p=%i\n", *p);
free(p);
return 0;
}

par contre ce dernier programme ne libère pas la mémoire toute seule pour 2 valeurs ... qui sera libérée à la fin du programme ...

Lien vers le commentaire
Partager sur d’autres sites

Premierement nous ne sommes pas oblige de definir les membres de la fonction c, si tu ne pense aucun membre, le compilateur sait elle n;attend aucun paramettre par defaut. Donc aucun probleme. Deuxiemement, dans ma boucle for, je peux parfaitement ecrire int i; car comme je viens de le dire, c,est une boucle et non une fonction au sens propre du terme. Il ne declare absolument par 3 fois la variable i !!! En C++, on appelle cela la surdefinition de l'operateur ( );

Pour la ligne using stdnamespace, ce n'est pas du ANSI C, mais simplement une instruction LINUX, pour faire appel a la bibliotheque standard.

Lien vers le commentaire
Partager sur d’autres sites

Euh tu connais la différence entre C et C++ ;)

Il faut choisir entre les deux, ici, à priori, c'est du C...

ça implique :

-déclaration de toutes les variables au début de la fonction

-pas d'utilisation de new ...

-pas de cout<<

Et après, il suffit de faire de l'allocation dynamique avec des malloc et des free pour libérer la mémoire ...

Et ce serait bien de bien connaître les pointeurs ...

Lien vers le commentaire
Partager sur d’autres sites

Pourquoi dois je choisir entre C et C++, l'avantage du C++, c'est justement qu'il permet le melange C et C++. Le compilateur C++, reconnait toutes les instructions du C. Le C++ n'est rien d'autre que du C auquel on a rajouté le concept d'objet (heritage, constructeur destructeur, surdefinission d'operateur, template,...)

Mais le plus triste c'est que je remarque ici que certaines personnes croient avoir tout compris et se permettent de donner des leçons de morale, alors que mon premier poste etait scencé suciter l'interret des nouveau programmeur en C. ce n'est pas pour rien que j'ai appeller ce poste " touvez l'erreur" ... je savais à la base que le programme etait sencer se planter. c'etait un petit execice quoi, rien de plus, meme si certain l'ont mal interprété.

D'ailleur si vous relisez les reponses, certaines sont completement floux ou carrément erronées.

Voilà, mais bon apparemment ceratin se declare vite comme des specialistes et donne des conseil assez deplacer sans meme connaitre le statut de la personne qui poste!!!

Lien vers le commentaire
Partager sur d’autres sites

Eh bien, je dirais aussi que l'énoncé est un peu flou ...

En plus, je ne pense pas que ceux qui débutent fassent bien la différence entre tous les languages ... les pointeurs, l'opérateur new, l'allocation dynamique ...

Parce que là, le problème, c'est qu'en plus, il y a plusieurs fautes, selon le contexte ...

Je critique surtout la tournure du premier post ... si c'était une sorte de "petit jeu" ... pourquoi ne pas l'avoir explicitement énoncé comme tel ?

Perso, j'avais pas du tout compris ça ...

(et puis, demander de chercher une erreur sur un programme qui marche (presque :mdr: ...)

Lien vers le commentaire
Partager sur d’autres sites

debuthmx,

Je trouve ton initiative très INtéressante : c'est en effet un bon exercice pour les débutants en C ou C++ que de corriger des programmes simples. Sans doute aurais-tu du être plus précis quant à la teneur de ton message afin d'éviter que les utilisateurs du forum prenne ton post pour un appel à l'aide.

Que dis-tu d'un titre "[Exercice pour débutant] Trouver l'erreur" ?

Bonne continuation !

Lien vers le commentaire
Partager sur d’autres sites

Ah c'était une erreur volontaire ? Hé ben fallait deviner...

Surtout qu'après ma réponse tu n'as pas dit "ok t'as bon" mais tu as au contraire persisté. C'est ce qui m'a un peu énervé, tu m'excuseras, mais je ne voulais pas laisser des fautes sur un forum.

Maintenant, si tu veux refaire des jeux du même style, précise-le, ça m'évitera de perdre mon temps :eeek2:

(Et, si ta remarque concernant les "spécialistes" m'était adressée, sache que oui, je suis un spécialiste, et pas autoproclamé. Paraît même que j'ai fait des études pour... :mdr: Et c'est quoi, ton "statut" ?)

[mode énervé off]

Lien vers le commentaire
Partager sur d’autres sites

Ah c'était une erreur volontaire ? Hé ben fallait deviner...

Surtout qu'après ma réponse tu n'as pas dit "ok t'as bon" mais tu as au contraire persisté. C'est ce qui m'a un peu énervé, tu m'excuseras, mais je ne voulais pas laisser des fautes sur un forum.

Maintenant, si tu veux refaire des jeux du même style, précise-le, ça m'évitera de perdre mon temps :keskidit:

(Et, si ta remarque concernant les "spécialistes" m'était adressée, sache que oui, je suis un spécialiste, et pas autoproclamé. Paraît même que j'ai fait des études pour... :mdr: Et c'est quoi, ton "statut" ?)

[mode énervé off]

+1

prochaine fois prévient que c est un jeu grrrrrr

Lien vers le commentaire
Partager sur d’autres sites

Archivé

Ce sujet est désormais archivé et ne peut plus recevoir de nouvelles réponses.

×
×
  • Créer...