1

Bonjour tout le monde,

j'ai vraiment besoin d'aide pour mon code:


char **matrice;

matrice=(char**)malloc(27*sizeof(char*));

for(i=0; i<28; i++)
{
matrice[i]=(char *)malloc(29*sizeof(char));
}
//remplit la matrice

matrice[0] = "########\n";
matrice[1] = "# #\n";
matrice[2] ="# $## ###\n";
matrice[3] ="# ## ##\n";
matrice[4] ="#@ .# #\n";
matrice[5] ="### #\n";
matrice[6] =" # ######\n";
matrice[7] =" ####";

matrice[4][1]='@';

Ca me fait un segmentation fault a la derniere ligne. Pourtant je peut afficher ce qu'il y a dans cette case (sans la modifier). (desolee pour les accents, je suis sur un clavier americain).

Merci beaucoup pour votre aide.

liza

2

Alors :


char **matrice;

        matrice=(char**)malloc(27*sizeof(char*));

        for(i=0; i<28; i++)
        {
                matrice[i]=(char *)malloc(29*sizeof(char));
        }


Oui ok

        //remplit la matrice

        matrice[0] = "########\n";
        matrice[1] = "#      #\n";
        matrice[2] ="# $##  ###\n";
        matrice[3] ="#   ##   ##\n";
        matrice[4] ="#@  .#    #\n";
        matrice[5] ="###       #\n";
        matrice[6] ="  #  ######\n";
        matrice[7] ="  ####";

        matrice[4][1]='@';


l'affectation d'une chaine de caractere ( aka qq chose entre des " ) dans un char * / char[] (aka un tableau de char) ne se fait QUE avec les fonction strcpy, et a la limite memcpy.

faire un matrice[x] = "...."; pourtant valide syntaxiquement, n'est pas valide au moment de l'execution.

Je te conseille de plutot regarder le man de strcpy, et si tu est sous windows, de regarder dans la doc de msdn pour strcpy.
avatar
Proud to be CAKE©®™


GCC4TI importe qui a problème en Autriche, pour l'UE plus et une encore de correspours nucléaire, ce n'est pas ytre d'instérier. L'état très même contraire, toujours reconstruire un pouvoir une choyer d'aucrée de compris le plus mite de genre, ce n'est pas moins)
Stalin est l'élection de la langie.

3

note: met des espaces ou des balises vides entre des [x ] (avec x= nombre) car sur le forum ça correspond à des balises de couleur happy (tu peux éditer ton post)
avatar
Que cache le pays des Dieux ? - Forum Ghibli - Forum Littéraire

La fin d'un monde souillé est venue. L'oiseau blanc plane dans le ciel annonçant le début d'une longue ère de purification. Détachons-nous à jamais de notre vie dans ce monde de souffrance. Ô toi l'oiseau blanc, l'être vêtu de bleu, guide nous vers ce monde de pureté. - Sutra originel dork.

4

cross -- à la bourre

5

Tiens bizzare, [ pre ] ajoute des espace devant les [ sorry

edit: Xi#5 :

index.php?f=D16803D7
avatar
Proud to be CAKE©®™


GCC4TI importe qui a problème en Autriche, pour l'UE plus et une encore de correspours nucléaire, ce n'est pas ytre d'instérier. L'état très même contraire, toujours reconstruire un pouvoir une choyer d'aucrée de compris le plus mite de genre, ce n'est pas moins)
Stalin est l'élection de la langie.

6

(je ne les vois pas perso)
avatar
Que cache le pays des Dieux ? - Forum Ghibli - Forum Littéraire

La fin d'un monde souillé est venue. L'oiseau blanc plane dans le ciel annonçant le début d'une longue ère de purification. Détachons-nous à jamais de notre vie dans ce monde de souffrance. Ô toi l'oiseau blanc, l'être vêtu de bleu, guide nous vers ce monde de pureté. - Sutra originel dork.

7

st que quand tu fais un matrice[0] = "########\n"; en fait ce qui se passe c'e tu modifies le pointeur qui se trouve dans la case matrice[0]
en gros tu écrases la valeur renvoyée par malloc (donc tu ne pourras plus libérer la mémoire allouée) et tu la remplaces par l'adresse de la chaine de caractère à l'intérieur de ton programme. c'est juste un pointeur qui est changé, il n'y a pas de recopie

=>strcpy comme l'a conseillé godzil

mais sinon une question plus technique :
les chaines sont dans le segment data du programme c'est bien ça ?
et il y a un seqfault car le segment est en lecture seule ? (ou tout au moins une partie de ce segment)
avatar

8

ça dépend de l'archi (pour la mémoire ségmenté)
Perso sur un PowerPC, la mémoire n'est (de mémoire) pas segmenté en data/code comme les x86, et le code provoque un "Bus Error"

Si la chaine etait déclaré comme const ça pourrait marcher. Le cas est que la chaine, meme si elle est en dur dans le code généré n'est pas dans une zone mémoire valide et utilisable (bref pas de SMC quelque pars)


Et il faut faire attention car :
char blabla[] = "blabla";
est valide
char blabla[512];
blabla = "blabla";

n'est PAS valide
avatar
Proud to be CAKE©®™


GCC4TI importe qui a problème en Autriche, pour l'UE plus et une encore de correspours nucléaire, ce n'est pas ytre d'instérier. L'état très même contraire, toujours reconstruire un pouvoir une choyer d'aucrée de compris le plus mite de genre, ce n'est pas moins)
Stalin est l'élection de la langie.

9

desolee pour les crochets.

matrice_jeu [ 0] = "########\n";
matrice_jeu [ 1] = "# #\n";
matrice_jeu [ 2] ="# $## ###\n";
matrice_jeu [ 3] ="# ## ##\n";
matrice_jeu [ 4] ="#@ .# #\n";
matrice_jeu [ 5] ="### #\n";
matrice_jeu [ 6] =" # ######\n";
matrice_jeu [ 7] =" ####";

matrice [5] [1] = '@';

j'espere que c'est plus lisible comme ca.

Nu: qu'est-ce que tu veux dire par segment data?

Si j'ai bien compris, vous voulez dire qu'au lieu de matrice [ i] = "...";
je devrais ecrire strcpy(matrice [ i], "...");

10

liza :
Nu: qu'est-ce que tu veux dire par segment data?
il veut parler de tes chaînes de caractères : elles sont en fait stockées avec ton programe, mais pas dans la partie où y'a le code, mais dans la partie où il y a les données (data).
matrice[ 4] = "...."
donc matrice[ 4] pointe vers la chaine de caractère, donc dans les données de ton programme
puis avec matrice[ 4][ 1]='@'; tu essayes d'écrire dans ces données, ce qui est interdit.
liza :
Si j'ai bien compris, vous voulez dire qu'au lieu de matrice [ i] = "..."; je devrais ecrire strcpy(matrice [ i], "...");
toutafé.

11

Depuis quand on ecrit des caractéres dans des matrices ? picol
Tu veux pas plutot faire un tableau de chaine ?

12

un tableau de chaînes, c'est un tableau de tableaux de caractères, autrement dit une matrice de caractères... (enfin, sauf que les longueurs de chaque chaîne ne sont pas forcément les mêmes)

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

13

c'est exactement ce qu'elle a fait : un tableau de chaine$

liza> voila c'est ce que hibou a répondu mais en fait je posais la question à ceux qui connaissent bien l'architecture des programmes etc
avatar

14

Oui c'est un tableau de chaines (ou un tableau bidimentionnel de caractères), rien a voir avec ca : http://fr.wikipedia.org/wiki/Matrice_(math%C3%A9matiques)

15

Boaf... ca peut etre vu comme cela... de tte facon, ces considération ne sont pas interessantes pour le sujet

16

hello tout le monde!!!

Merci beaucoup pour vos réponses. Je l''ai fait avec strcpy et ça marche maintenant.
Pour ce qui est de savoir si c'est vraiment une matrice ou un tableau de chaines de caracteres tu as raison the_chojin, c'est plutôt ce que je voulais faire (le tableau de chaines) mais comme je l'ai appelée matrice dans mon code j'ai fini par ne plus vraiment faire la différence.

Maintenant, le problème que j'ai c'est encore un segmentation fault mais au moment de la désallocation. En fait je la fait comme ça:

for( i = 0; i < nb_lignes; i++)
{
free(matrice_jeu [ i]);
}

free(matrice_jeu);

Je ne vois pas où est le problème.

Et il y a autre chose. Si j'écris la matrice dans un fichier texte et que je la récupère ligne par lignes en faisant

fgets(matrice [ i],nb_colonnes+2 ,fich); (fich est mon pointeur sur le fichier et le nb_colonnes (nombre de colonnes) est correctement récupéré)

j'ai un segmentation fault au niveau des malloc. Et là je ne comprends rien du tout.

Ça fait beaucoup de questions à la fois, je sais, mais c'est mas première année d'informatique et je suis loin de tout maîtriser (vous avez du vous en rendre compte lol).

liza

17

oui, le code pour libérer est correct (enfin, sous réserve que l'allocation soit correcte et que les pointeurs n'aient pas été modifiés entre-temps), donc si ça plante c'est peut-être que tu as corrompu la mémoire avant... le problème avec les corruptions de mémoire c'est qu'il faut regarder tout le code pour savoir ce qui fait foirer : par exemple, dans un premier temps tu peux désactiver tout ce qu'il y a entre malloc() et free() pour vérifier que ça marche effectivement, puis réactiver progressivement une partie du code jusqu'à ce que ça re-plante ^^


pour fgets, d'où vient le +2 ? combien d'octets as-tu alloué à matrice[i] ?

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

18

nEUrOO
:de tte facon, ces considération ne sont pas interessantes pour le sujet

Bien sur que si, parce ce qu'elle était peut être en train de faire quelque chose de faux (char à la place de int/float/double/...).

Tu as certainement des pointeurs non alloués que tu essais de libérer, rajoute un if(matrice_jeu [ i ] != NULL) mais corriger la facon dons tu remplis le tableau peut être une bonne option aussi wink
Le fgets dois planter si tu essais de lire aprés la fin du fichier ...
Le plus simple pour toi serais d'apprendre à te servir d'un debugger (ca change une vie ^^).

19

depuis le début, elle bosse avec ca, y'a certainement une raison !

20

Il y a une petite erreur: Tu alloues de la place pour 27 lignes, mais tu en remplis 28 (de 0 à 27)
avatar
Maintenant j'ai la flemme de garder une signature à jour sur ce site. Je n'ai même plus ma chaîne Exec sous la main.

21

je viens de regler le probleme de la desallocation.
the_chojin et Link: vous aviez raison c'etait juste un probleme de nombre de lignes.
maintenant je me colle a mon probleme de fichier.
Pollux: oufff!!!! je n'ai pas ete obligee de "reprendre" tout mon code (mais si ca se trouve je devoir le faire a cause du fichier. arggg!!!).
nEUrOO: en effet il y a une raison. ca fait partie d'un projet que j'ai a faire, un espece de sokoban en mode manuel et automatique et le prof test nos codes avec des matrices contenues dans des fichiers.

merci encore pour votre aide a tous.

22

dans ce cas-là c'est effectivement parfaitement raisonnable d'appeler ça une matrice de caractères, puisque toutes les lignes ont le même nb de colonnes, et les lignes et les colonnes jouent un rôle similaire oui

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

23

liza> Par contre la fonction strcpy est à proscrire. Oublie définitivement son existence et utilise strncpy à la place.

Pollux> exact, mais un tableau de pointeurs sur tableaux n'est pas le type de structure de données approprié du coup.

24

spectras :
liza> Par contre la fonction strcpy est à proscrire. Oublie définitivement son existence et utilise strncpy à la place.
confus

25

[cross, je parlais à spectras]
voui ^^

(par contre strncpy ça sux, strcpy pawa smile [et std::string powa encore plus] de toute façon dans 80% des cas strncpy ne dispense pas de faire une vérification de la longueur de la chaîne, donc autant éviter de prendre de mauvaises habitudes en faisant semblant que tout marche sans rien vérifier... sans même parler du fait qu'étant donné que strncpy ne crée pas nécessairement une chaîne terminée par un 0, ça peut tjs créer des vulnérabilités subtiles qui n'apparaissent jamais en tps normal embarrassed)

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

26

"[et std::string powa encore plus]" => oui, mais hélas si on demande en C, on peut pas s'en servir

par contre pour strncpy, oui ça peut créer une chaine non terminée par un caractère nul, mais c'est moins dangereux qu'un débordement, et ça peut se contourner assez facilement en forçant le dernier caractère du tableau à 0 après l'appel.

mais la meilleure solution c'est encore celle de OpenBSD

27

Tu as la même chose avec les nouvelles fonctions C-Run-Time de Visual Studio 2005, ou encore avec les fonctions de strsafe.h... (Comme StringCchCopy/StringCbCopy, StringCchCat, et surtout StringCchPrintfEx!)
avatar
Maintenant j'ai la flemme de garder une signature à jour sur ce site. Je n'ai même plus ma chaîne Exec sous la main.

28

Euh....
et surtout StringCchPrintfEx
pourquoi surtout printf ? Que fait snprintf de mal pour toi ?

Parce que je regarde la fonction que tu indiques...
HRESULT StringCchPrintfEx(      
    LPTSTR pszDest,
    size_t cchDest,
    LPTSTR *ppszDestEnd,
    size_t *pcchRemaining,
    DWORD dwFlags,
    LPCTSTR pszFormat,
     ...
);

Outre le fait que c'est assez ignoble, je vois même pas ce qu'elle apporte par rapport à snprintf ?

En fait à part StringCchCopy je vois pas trop l'intérêt des autres ?

29

En plus plus se snprintf :
1) Elle assure que le buffer sera terminé par un caractère nul (c'est pas le cas de snprintf, du moins chez eux :/ )
2) Elle retourne l'adresse de la suite du buffer et la taille restante, parfait pour utiliser plusieurs de ces fonctions à la suite.

De plus, la version Cb permet de passer un sizeof au lieu d'un nombre de caractères, utile quand on programme en TCHAR ou en UNICODE.
avatar
Maintenant j'ai la flemme de garder une signature à jour sur ce site. Je n'ai même plus ma chaîne Exec sous la main.

30

1) snprintf renvoie toujours une chaîne terminée par un caractère nul
2) cette fonction est déjà inclue dans snprintf (voir le %n)
De plus, la version Cb permet de passer un sizeof au lieu d'un nombre de caractères
snprintf prend en paramètre un nombre d'octets