2009-07-30 6 views

Répondre

12

Techniquement, cela ne fait pas partie de C++. Vous pouvez faire des tableaux de longueur variable dans C99 (ISO/IEC 9899: 1999) mais ils ne font pas partie de C++. Comme vous l'avez découvert, ils sont pris en charge en tant qu'extension par certains compilateurs.

10

G ++ prend en charge une fonctionnalité C99 qui permet des tableaux de taille dynamique. Ce n'est pas standard en C++. G ++ a l'option -ansi qui désactive certaines fonctionnalités qui ne sont pas en C++, mais ce n'est pas l'un d'entre eux. Pour G ++ rejeter ce code, utilisez l'option -pedantic:

 
$ g++ -pedantic junk.cpp 
junk.cpp: In function ‘int main()’: 
junk.cpp:4: error: ISO C++ forbids variable-size array ‘pz’ 
6

Si vous voulez un tableau dynamique sur la pile:

void dynArray(int x) 
{ 
    int *array = (int *)alloca(sizeof(*array)*x); 

    // blah blah blah.. 
} 
+6

Cela fonctionne, mais je voudrais ajouter la citation suivante de "man alloca": "La fonction alloca() dépend de la machine et du compilateur, son utilisation est déconseillée." –

2

En pratique, si vous voulez faire un tableau dynamique, vous devez utiliser std :: vecteur, comme dans:

 
#include <iostream> 
#include <cstdlib> 
#include <vector> 

int main(int argc, char* argv[]) 
{ 
    int size; 
    std::cin>>size; 
    std::vector<int> array(size); 
    // do stuff with array ... 
    return 0; 
} 

Si vous êtes curieux sur la syntaxe, alors ce que vous recherchez est:

 
//... 
int* array = new int[size]; 
// Do stuff with array ... 
delete [] array; 
//... 

Aucune de ces zones n'est allouée avec le stockage local. Un tableau de taille dynamique qui est automatiquement alloué en utilisant le stockage local n'est pas actuellement pris en charge en C++ standard, mais est pris en charge dans le standard C actuel.

+0

L'allocation de mémoire sur le tas n'est-elle pas nouvelle? J'avais l'impression que OP voulait l'attribuer sur la pile, vu le titre de la question. – mrduclaw

+1

ne change pas le fait que le vecteur est la solution correcte. Dans ce cas, il ne peut pas avoir ce qu'il demande. Le vecteur est le plus proche. (Et non, je ne considère pas alloca dans un contexte C++) – jalf

+1

Pour les applications qui nécessitent des performances critiques dans certains cas, alloca est absolument la bonne réponse si le compilateur ne supporte pas la syntaxe "int array [x]". Les allocations basées sur des piles, typiquement une seule instruction soustrayant du pointeur de la pile, sont bien plus rapides que celles du tas. –

13

Voici votre réponse combinaison de tous ces petits:

Votre code est maintenant droit pas C++ standard. Il est norme C99. C'est parce que C99 vous permet de déclarer des tableaux dynamiquement de cette façon. Pour clarifier, il est également la norme C99:

#include <stdio.h> 

int main() 
{ 
    int x = 0; 

    scanf("%d", &x); 

    char pz[x]; 
} 

C'est ne rien standard:

#include <iostream> 

int main() 
{ 
    int x = 0; 
    std::cin >> x; 
    char pz[x]; 
} 

Il ne peut pas être la norme C++, car ce tableau constant nécessaire tailles, et il ne peut pas être la norme C parce que C n'a pas std::cin (ou espaces de noms, ou classes, etc ...)

Pour rendre la norme C++, faites ceci:

int main() 
{ 
    const int x = 12; // x is 12 now and forever... 
    char pz[x]; // ...therefore it can be used here 
} 

Si vous voulez un tableau dynamique, vous pouvez faire ceci:

#include <iostream> 

int main() 
{ 
    int x = 0; 
    std::cin >> x; 

    char *pz = new char[x]; 

    delete [] pz; 
} 

Mais vous devriez faire ceci:

#include <iostream> 
#include <vector> 

int main() 
{ 
    int x = 0; 
    std::cin >> x; 

    std::vector<char> pz(x); 
} 
3

Allouer des tableaux de longueur variable sur la pile est un bon idée, car il rapide et ne fragmente pas la mémoire. Mais C++ Standard ne le supporte malheureusement pas. Vous pouvez le faire en utilisant l'enveloppe de modèle à la fonction alloca. Mais en utilisant alloca n'est pas vraiment une norme conforme.

Standard est d'utiliser std :: vector avec allocateur personnalisé si vous voulez éviter la fragmentation de la mémoire et accélérer les allocations de mémoire. Jetez un oeil sur boost::pool_alloc pour un bon exemple d'allocateur rapide.

Questions connexes