2009-04-10 9 views
47

J'utilise le C++ depuis quelques années, et aujourd'hui j'ai vu du code, mais comment cela peut-il être parfaitement légal?La taille du tableau au moment de l'exécution sans allocation dynamique est autorisée?

int main(int argc, char **argv) 
{ 
    size_t size; 
    cin >> size; 
    int array[size]; 
    for(size_t i = 0; i < size; i++) 
    { 
     array[i] = i; 
     cout << i << endl; 
    } 

    return 0; 
} 

Compilé sous GCC.

Comment la taille peut-elle être déterminée à l'exécution sans new ou malloc? Pour vérifier une deuxième fois, j'ai fait des recherches sur google et tous les codes similaires aux miens sont censés donner une erreur de taille de stockage.

Même le programme de programmation C++ de Deitel p. 261 états sous Common Programming Error 4.5:

Seules les constantes peuvent être utilisées pour déclarer la taille des tableaux automatiques et statiques.

Enlight moi.

+2

Notez que DMA signifie "l'accès direct à la mémoire" - Je pense que vous vous posez sur l'allocation dynamique –

+2

C ou C++? Choisissez _one_. –

+1

Encore une fois, choisissez un: C ou C++. Cette question est explicitement et seulement sur C; il ne devrait pas y avoir de balise C++. –

Répondre

49

Ceci est valable en C99.

La norme C99 prend en charge les matrices de taille variable sur la pile. Probablement votre compilateur a choisi de supporter cette construction aussi.

Notez que ceci est différent de malloc et new. gcc alloue le tableau sur la pile, comme il le fait avec int array[100] en ajustant simplement le pointeur de la pile. Aucune allocation de tas n'est effectuée. C'est à peu près comme _alloca.

+7

Je suis tombé sur ce même scénario dans un fichier de notre base de code qui a été écrit il y a des mois.J'ai été déconcerté, tout comme le reste de l'équipe, quant à savoir pourquoi il a été compilé. Dans notre cas, la taille du tableau a été calculée avant de déclarer le tableau (ce qui ne devrait pas non plus être autorisé). Quoi qu'il en soit, un défi est sorti. Toute personne qui pourrait répondre à la question de savoir si c'est légal obtient une tarte pop. Si vous êtes à Seattle, faites le moi savoir. J'ai une tarte pour vous. –

+0

Pouvez-vous fournir quelques informations/liens sur le fonctionnement interne de la pile dans ce cas? Est-ce que cela introduit des frais généraux dans l'exécution? – balki

+1

@balki La surcharge est mineure, car elle incrémente/décrémente le pointeur de la pile. Le comportement de la pile peut être essentiellement identique au cas normal si vous enregistrez le pointeur de la pile d'origine au début de la fonction. –

7

Il est valid uniquement en C99. La prochaine fois que vous pouvez essayer de vérifier votre code dans un reliable compiler.

4

Il est valide C99, il n'est pas valide C++. C'est l'une des quelques différences entre les deux langues.

+2

Je suppose que cela va être pris en charge en C++ 0x –

+0

Non selon la section 8.3.4 du projet de norme. –

+2

il ne sera jamais inclus dans C++ 1x: D mais espérons dynarray obtient po je l'aimerais. donc vous pouvez faire dynarray a (some_size); et l'allouer efficacement, éventuellement avec compilateur hax comme _alloca et ainsi de suite. –

18

Ceci est connu comme VLAs (array de longueur variable). C'est standard dans c99, mais gcc le permet dans le code C++ comme extension. Si vous voulez rejeter le code, essayez d'expérimenter avec les options -std=standard, -ansi et -pedantic.

0

Vous pouvez dynamiser la taille d'un tableau si vous utilisez le compilateur Dev-Cpp. Je l'ai essayé et je n'ai pas eu d'erreur mais sur les compilateurs Visual C++ et Visual Studio, ce n'est pas possible. Je pense que la raison est que dev-C++ affecte un nombre positif à l'entier non initialisé et quand on lui donne un nombre, il est remplacé par celui donné. mais peut-être d'autres compilateurs donnent null aux variables non initialisées.

+0

La plupart des compilateurs n'attribuent rien aux variables locales non initialisées, ils semblent généralement contenir tout ce qu'ils ont dans la mémoire qu'ils occupent jusqu'à ce qu'ils soient assignés par le programme. Il semble que le Dev-C++ que vous avez référencé soit un IDE au dessus de MinGW, qui inclut un port de GCC comme compilateur. Comme indiqué dans les autres réponses, les VLA ne sont pas standard en C++, mais certains compilateurs (y compris g ++) les supportent quand même. – jerry

+0

Dev-C++ n'est pas un compilateur. Visual Studio n'est pas non plus. Dev-C++ utilise GCC/G ++ comme compilateur, tandis que Visual Studio utilise cl (back-end du compilateur de Microsoft). À eux seuls, Dev-C++ et Visual Studio sont des environnements de développement intégrés (IDE). C'est une distinction importante à faire. Dev-C++ n'assigne rien. Le compilateur fait cela. – Elkvis

-1

Les matrices de longueur variable (VLA, variable length array) sont prises en charge dans la norme C++ 14, qui a récemment été acceptée et en attente de publication.

+1

Les VLA ne font toujours pas partie de la norme. Il y a un [dynarray] (http://en.cppreference.com/w/cpp/container/dynarray) TS, mais pour l'instant il n'est pas ratifié. – Jason

0

Ce code s'exécute dans le compilateur GNU GCC.

#include<bits/stdc++.h> 

int main(int argc, char **argv) 

{ 
    size_t size; 

    std:: cin >> size; 

    int array[size]; 

    for(size_t i = 0; i < size; i++) 

{ 

array[i] = i; 

     std:: cout << i; 

} 

    return 0; 
}