# problème C(3)



## vibra (8 Mars 2008)

Bonjour,
Je suis sur mac OS X, et j'utilise Xcode pour programmer en C.
Je suis entrain de faire un code, mais il y a un problème à l'intérieur et je n'arrive pas à le trouver.
Voici le code :

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

int main(int argc, char *argv[])
{
    int i = 0;
    int j=0;
    int *presence = NULL;
    int taille = 6;
    presence = malloc(taille * sizeof(char));
    if (presence == NULL)
    {
        exit(0);
    }
    for (i = 0 ; i < taille ; i++)
    {
        presence[i] = 0;
        //printf("%ld", 1);
    }
    for (i = 0 ; i < taille ; i++)
    {
        printf("%ld\n", presence[i]) ;
    }
    free(presence);

    return 0;
}
```
En fait ce code crée un tableau par allocation dynamique et le remplit de 0, puis affiche chaque cellules du tableau. Donc normalement on devrait avoir que des 0. Sauf qu'il y a un 1 qui se glisse dedant (toujours au même endroit). C'est d'autant plus bizarre que il y a une instruction que j'ai mis en commentaire et que quand on la "décommentarise" (donc elle est exécutée) le 1 disparait alors que l'instruction est un printf
Je ne comprend pas ce qui se passe.
Pouvez vous m'aider svp ?


----------



## ntx (8 Mars 2008)

1/ Si je dis pas de bêtise - cela fait longtemps que je suis passé au C++ - malloc renvoie un void* donc un petit cast en int* ne pourrait pas faire de mal 
2/ Tu alloues ton tableau avec une taille d'élément de char (1 octet) et pas de int (4 octets sur Intel Core2Duo)


----------



## Céroce (10 Mars 2008)

Même réponse que ntx en plus explicite:

La taille à réserver passée à malloc est exprimée en octets.
Tu réserves 6 octets, mais tu indexes la zone allouée par un pointeur d'int (un int fait 32 bits sous Mac OS X, donc tu fais un dépassement de tableau.

Essaie malloc(taille * sizeof(int)), ça ira mieux.


----------



## vibra (10 Mars 2008)

Vous avez raison, je me suis trompé, je voulais faire un tableau char et pas int ! Et dire que j'ai passé au moins une heure à rechercher cette erreur(c'est le métier qui rentre).
Il y a juste un truc que je ne comprends pas : pourquoi quand on rajoute la commande qui est en commentaire, ça fonctionne ?


----------



## Céroce (10 Mars 2008)

vibra a dit:


> Il y a juste un truc que je ne comprends pas : pourquoi quand on rajoute la commande qui est en commentaire, ça fonctionne ?



A vrai dire, je ne sais pas trop.
Ce n'est pas le même programme, et l'allocation mémoire au processus est différente, ou quelque chose comme ça. Quand on fait des dépassements, tout devient très hasardeux, d'ailleurs c'est ce qui fait que certains bugs ne sont pas reproductibles sur deux machines différentes.


----------



## grumff (10 Mars 2008)

Tu tapes dans des zones mémoires que tu n'as pas réservées et qui sont peut-être utilisées pour d'autres choses, alors selon ce qui s'y trouve et ce qui s'y passe, les réactions sont différentes. En ajoutant une ligne tu modifies l'emplacement d'une partie de ton code en mémoire, ça change tout. Les erreurs de pointeur en C c'est une vrai plaie à déboguer, parce que les résultats peuvent être très inattendus. Quand t'as des réactions plutôt étranges, faut te dire que ça vient de là.


----------



## vibra (10 Mars 2008)

Ok, merci du conseil.
Merci à tous.


----------



## vibra (14 Mars 2008)

Bonjour,
J'ai une question : comment peut-on faire pour mettre un fichier utilisé par le programme dans un autre dossier que le dossier debug ?


----------



## Didier Guillion (14 Mars 2008)

Si tu rajoute ton fichier au projet, il sera copié lors de la compilation.
Tu peut egalement sous XCode, faire un click droit et choisir "Add>New build phase>New copy files build phase".

Ton programme accedera au fichier via un chemin relatif à ton bundle.

Cordialement


----------



## vibra (14 Mars 2008)

D'accord, mais comment fais t'on pour écrire le chemin relatif ?


----------



## Didier Guillion (14 Mars 2008)

Ben, avec des slashes entre les noms des dossiers (comme sous le terminal)

Vois egalement ceci :

http://developer.apple.com/technotes/tn/tn2015.html

Cordialement


----------



## vibra (16 Mars 2008)

J'ai encore un problème. J'ai fais un programme qui ouvre un fichier, et qui m'affiche un message d'erreur si le fichier n'a pas  pu être ouvert. Le fichier en question est dans le dossier par défaut :  build/Debug. Donc je n'ai pas mis de chemin relatif. Le problème c'est que quand je lance le programme à partir d'Xcode, le fichier est ouvert correctement, alors que quand je lance l'exécutable, le fichier n'est pas ouvert et le message d'erreur s'affiche. D'où vient le problème ?


----------



## Didier Guillion (16 Mars 2008)

Build/debug est le dossier ou XCode créé ses fichiers de travail. Ce n'est en aucun cas le dossier de ton application.
Je te conseille de lire un peu de doc sur les "bundles" des application pour comprendre comment cela fonctionne.

Cordialement


----------



## vibra (16 Mars 2008)

D'accord, je vais m'y mettre, mais pourquoi ça marche en passant par Xcode, et pas en exécutant l'exécutable ?


----------



## tatouille (17 Mars 2008)

utilise calloc dans ton cas c est quant meme plus rapide


```
(int*) calloc (len, sizeof(int));
```


----------



## vibra (17 Mars 2008)

A quoi sert cette instruction et que faut-il mettre à la place de "len" ?
Merci, mais tout ça ne répond pas à ma question : "mais pourquoi ça marche en passant par Xcode, et pas en exécutant l'exécutable ?"


----------



## Eul Mulot (17 Mars 2008)

Ton exécutable généré par XCode et que tu lances à la main n'est sûrement pas au même niveau que celui qu'il utilise lors de son exécution via XCode, et si le path de ton fichier est un path relatif et non absolu, ben fatalement il ne va pas le retrouver, puisque le path relatif de ton fichier à ouvrir n'est pas le même dans les deux différents répertoire. Essaye plutôt de garder des paths absolus sauf cas précis pour ce genre de chose.


----------



## vibra (17 Mars 2008)

Ok, merci, je vais essayer.


----------



## tatouille (17 Mars 2008)

vibra a dit:


> A quoi sert cette instruction et que faut-il mettre à la place de "len" ?
> Merci, mais tout ça ne répond pas à ma question : "mais pourquoi ça marche en passant par Xcode, et pas en exécutant l'exécutable ?"



ce que tu appeles "taille"
et tu sizeof une int pas une char, ca n'a pas la meme size, essaye un peu de comprendre ce que tu fais


----------



## vibra (22 Mars 2008)

D'accord, mais à quoi sert concrètement calloc ?


----------



## grumff (22 Mars 2008)

Quasiment à la même chose que malloc, mais avec une syntaxe un peu plus adaptée aux tableaux.


----------



## vibra (22 Mars 2008)

Ok, merci.


----------

