CONNEXION
  • RetourJeux
    • Sorties
    • Hit Parade
    • Les + populaires
    • Les + attendus
    • Soluces
    • Tous les Jeux
    • Gaming
  • RetourActu Gaming
    • News
    • Astuces
    • Tests
    • Previews
    • Toute l'actu gaming
  • RetourBons plans
    • Bons plans
    • Bons plans Smartphone
    • Bons plans Hardware
    • Bons plans Image et Son
    • Bons plans Amazon
    • Bons plans Cdiscount
    • Bons plans Decathlon
    • Bons plans Fnac
    • Tous les Bons plans
  • RetourJVTech
    • Actus High-Tech
    • Intelligence Artificielle
    • Smartphones
    • Mobilité urbaine
    • Hardware
    • Image et son
    • Tutoriels
    • Tests produits High-Tech
    • Guides d'achat High-Tech
    • JVTech
  • RetourCulture
    • Actus Culture
    • Culture
  • RetourVidéos
    • A la une
    • Gaming Live
    • Vidéos Tests
    • Vidéos Previews
    • Gameplay
    • Trailers
    • Chroniques
    • Replay Web TV
    • Toutes les vidéos
  • RetourForums
    • Hardware PC
    • PS5
    • Switch 2
    • Xbox Series
    • Switch
    • Pokemon pocket
    • FC 25 Ultimate Team
    • League of Legends
    • Tous les Forums
  • PC
  • PS5
  • Xbox Series
  • Switch 2
  • PS4
  • One
  • Switch
  • iOS
  • Android
  • MMO
  • RPG
  • FPS
En ce moment Genshin Impact Valhalla Breath of the wild Animal Crossing GTA 5 Red dead 2
Liste des sujets

[C] Question sur malloc

Chaos_Clad
Chaos_Clad
Niveau 10
09 avril 2008 à 11:20:06

Bonjour à tous,

je viens vous poser une question qui va sûrement être débile mais qui me perturbe.
J'ai toujours appris, lu et fait de manière à ce que lorsqu'un tableau dont la taille est inconnue à l'exécution, je fais un bel appel à malloc pour le créer dynamiquement.
J'ai toujours appris et lu qu'il ne fallait pas faire ceci :

"int nb;
scanf("%d", &nb);
int tab[nb];"

mais bien int* tab = malloc(sizeof(int) * nb);

Mais voilà j'ai un ami qui a initialisé un tableau à l'aide d'une variable remplie à partir d'un scanf, donc à l'exécution et... ça marche -_-"

Toute ma conception du monde s'ébranle et je suis au bord du gouffre.
Pourquoi et comment a-t-il pu faire ça ? :(

UltraSPARC
UltraSPARC
Niveau 2
09 avril 2008 à 12:37:50

Comment ? :d) Les variables locales étant sur la pile, pour réserver tab le compilateur a du faire un truc du genre :
pointeur_de_pile -= nb;
tab = pointeur_de_pile;
(du moins c'est ce que gcc fait).

Pourquoi ? :d) En fait en C90 ce genre de truc est impossible, alors qu'en C99 c'est accepté. Après je saurais pas dire pourquoi tout les tutos c du net le déconseillent. Peut-être pour un genre de rétro-compatibilité.

guyver2
guyver2
Niveau 10
09 avril 2008 à 15:03:33

gcc laisse passer ce genre de trucs ??? Je crois me souvenir que non. Si oui, faut-il lui filer des options spécifiques ?

godrik
godrik
Niveau 30
09 avril 2008 à 15:19:53

ca ne devrait pas marcher. Ce n'est pas dans la norme du C. En C, la taille de toutes les varaibles doit etre connu au moment de l'entré dans la fonction. Le code suivant est donc valide:

void fnct (unsigned int nb)
{
int tab[nb];
}

dnob700
dnob700
Niveau 10
09 avril 2008 à 20:12:31

ce n'est autorisé ni en C90 ni en C99. Mais par défaut GCC compile du C99 + des extensions qui lui sont propre lorsqu'elles ne sont pas en conflit avec la norme (sinon il faut les activer manuellement).

Et donc, entre autre, par défaut, gcc accepte les tableau de taille dynamique déclaré "statiquement". Mais ce n'est pas portable à un autre compilateur que GCC.

UltraSPARC
UltraSPARC
Niveau 2
09 avril 2008 à 21:01:47
  1. dnob700 Voir le profil de dnob700
  2. Posté le 09 avril 2008 à 20:12:31 Avertir un modérateur
  3. ce n'est autorisé ni en C90 ni en C99.

:d) ce n'est pas ce que dit la norme c99 : (§6.7.5.2)
http://www.open-std.org/JTC1/SC22/wg14/www/docs/C99RationaleV5.10.pdf

Mais par défaut GCC compile du C99 + des extensions qui lui sont propre lorsqu'elles ne sont pas en conflit avec la norme (sinon il faut les activer manuellement).

:d) De base c'est du c90 + extensions, puisque le c99 n'est pas encore totalement suporté par gcc :
http://gcc.gnu.org/c99status.html.
(tu peux tester un for (int i = 0; i; i++); si tu me crois pas)

Et donc, entre autre, par défaut, gcc accepte les tableau de taille dynamique déclaré "statiquement". Mais ce n'est pas portable à un autre compilateur que GCC.

:d) y a pas beaucoup (aucun ?) d'autres compilos que ceux basés sur gcc qui supportent le c99 donc ça serait pas étonnant.

Fvirtman
Fvirtman
Niveau 10
09 avril 2008 à 23:12:17

Je ne sais pas si c'est la norme récente du C (la 99) ou alors une permissivité de certains compilos, quoiqu'il en soit, ce ne sera surement pas tres portable (car tous les compilos ne sont pas passés en 99)

Apres, a mon avis, ce que doit faire le compilo, c'est remplacer par un pointeur et un malloc, et faire un free en sortant de la fonction, tout simplement.

Du coup, ou est stocké le tableau ? surement pas sur la pile, mais dans la zone de mémoire allouée dynamiquement ?
Moi je vote pour la zone dynamique, mais a confirmer :)

dnob700
dnob700
Niveau 10
09 avril 2008 à 23:38:50

UltraSPARC : effectivement, tu as raison. C'est bien accepté tout le temps par gcc mais comme une extension au c90 et au c++ (si elles sont activées).

fvirtman, j'ai regardé dans quelques dump d'assembleur et le compilo fait bien globalement ce que dit ultrasparc, même si il génère du code peut-être un peu long.

Toujours est-il que le C n'est pas censé, contrairement au c++, avoir besoin de runtime pour s'exécuter. Donc tu ne peut pas rajoutter des appels à malloc là où il n'y en a pas.

Chaos_Clad
Chaos_Clad
Niveau 10
10 avril 2008 à 11:03:25

Merci pour vos réponses.

J'ai testé ce même code sur DevC++ et Code::Blocks, je l'avais aussi compilé sous Centos, et ça passe, donc je sais pas trop. Ceci dit j'ai fait une vérification SdZ et il y a bien marqué que certains compilateurs acceptent cette écriture, mais qu'il est préférable d'utiliser malloc.

  1. include <stdio.h>

int main()
{
int nb;
scanf("%d", &nb);
int tab[nb];

tab[0] = 1;

printf("%d", tab[0]);

return 0;
}

________________________________________
Ma vidéo du moment :
http://youtube.com/watch?v=96Fm5SPsjD0 (Les Kiss Kool, à voir absolument :coeur: )

"Suicide par défénestration : encore une victime de Qt :( "

JujuDredd
JujuDredd
Niveau 10
10 avril 2008 à 21:53:00

Ouais mais bon, si comme moi vous compilez avec -Wall -ansi et -pedantic (et oui, je suis pedant :nah: ) je doute fortement qu'on puisse déclarer une variable après une instruction. Ou alors oui mais dans un autre sous-block.

Sous forums
  • Aide à l'achat Mac
  • Macintosh
  • Création de sites web
  • Création de Jeux
  • Linux
  • Programmation
  • Internet
  • Steam Deck
  • Hardware
La vidéo du moment