Le code ci-dessous est-il sûr à utiliser? D'une manière ou d'une autre, je pense que ce n'est pas une bonne façon de faire. Je sais qu'un meilleur moyen est Malloc (), Realloc (). Mais je veux comprendre où ce code possède le plus de risque. Comme le compilateur ne connaît pas la taille de l'allocation, comment la taille de la pile sera définie?
int array_call(int k) { int temp[k]; int = 0; int i = 0; for (i = 0;i<k;i++) { temp[i]=i; } return k; } int main() { int n; scanf("%d", &n); n=array_call(n); }
3 Réponses :
Si vous utilisez un compilateur qui ne prend pas en charge VLAS ( Array de longueur variable A> S), vous pourriez simplement avoir cette fonction allouer et revenir, un tableau avec la taille donnée. int *NewInitedArrayWithCount( unsigned int arrayCount )
{
int *array = (int *) malloc( arrayCount * sizeof( int ));
if ( array != NULL )
{
for ( int i = 0; i<arrayCount; i++ )
{
array[i] = (int) i;
}
}
return array;
}
int main()
{
unsigned int arrayCount;
scanf( "%u", &arrayCount );
int *array = NewInitedArrayWithCount( arrayCount );
// Do stuff
if ( array != NULL )
free( array );
return 0;
}
Il s'agit d'un exemple d'une matrice de longueur variable (VLA), où la taille de la matrice n'est pas connue avant l'exécution. Cette fonctionnalité a été introduite dans la révision de la langue de 1999, mais a été facultative lors de la révision de 2011.
Donc, le premier risque est que les VLAS ne sont pas universellement pris en charge - ce code peut ne pas compiler sur certaines plates-formes. Sur C2011 et plus tard, vous voudrez vérifier si la macro le Deuxième risque principal est que les VLAS ne peuvent pas être arbitrairement importantes - de nombreuses implémentations (sinon la plupart) tentent d'allouer de l'espace VLA à partir de la pile et d'empiler a tendance à être limitée. Si VLAS ne peut pas être déclaré au champ de fichier ou avec le < Code> statique code> mot-clé, ni des membres de __ stdc_no_vla __ code> a été définie avant d'essayer de les utiliser, quelque chose comme p>
k code> est trop grand 1 sup> Vous obtiendrez probablement une sorte d'erreur d'exécution irrécupérable. P>
struct code> ou
Union code> types. P>
De plus, VLAS ne peut pas être initialisé (C11 6.7.9P3)
Le code ci-dessous est-il sûr à utiliser? P> blockQuote>
NO. P>
de quelque manière que ce soit, je pense que ce n'est pas bon faire. Je sais qu'un meilleur moyen est Malloc (), Realloc (). Mais je veux comprendre où ce code possède le plus de risque. P> blockQuote>
Risque n ° 1: la fonctionnalité que vous comptez sur des tableaux de longueur variable, est facultative en C11 et plus tard, et absent (au moins non normalisé) dans C90. Seulement en C99 est-il à la fois standard et obligatoire. De nombreuses implémentations C vous rencontrerez de la mise en œuvre, mais il y a des éléments notables qui ne le font pas. Votre code ne compilera pas du tout sur ce dernier. P>
Risque n ° 2: C ne spécifie pas comment les VLAS automatiques sont implémentées, mais il est courant qu'ils soient alloués sur la pile. Dans de telles implémentations, il est relativement facile de causer l'échec du programme avec un débordement de pile en fournissant une valeur trop importante de
N code>. Il y a généralement (beaucoup) plus d'espace disponible pour une allocation dynamique avec
MALLOC () code> & co., Mais même s'il n'y avait pas, vous pouvez au moins détecter et récupérer à partir d'un
Malloc () < / code> échec. Similaire s'applique à la possibilité que
n code> soit donné en tant que nombre négatif. P>
Risque n ° 3: Vous utilisez une entrée d'utilisateur non validée de manière sensible. Il s'agit d'un échec majeur du protocole de programmation sécurisé. P>
comme compilateur ne sait pas La taille de l'allocation, comment la taille de la pile sera définie? P> blockQuote>
Vous supposez qu'il y a une pile, et que c'est là que vous ira le VLA. Ni n'est garanti. Il n'existe pas non plus d'exigence pour un comportement particulier dans ces implémentations où ces deux hypothèses tiennent. En pratique, cependant, le compilateur est raisonnablement susceptible d'allouer des membres VLA au sommet de la pile, au-dessus des membres non-VLA, et simplement d'ajuster le pointeur de pile de manière appropriée pour la valeur du
N code>. C'est un peu plus délicieux s'il y a plusieurs VLAS, mais totalement faisable. Cela fait partie des problèmes liés. P>
Pouvez-vous expliquer un peu plus loin: "Vous supposez qu'il y a une pile et que c'est là que le VLA ira. Ni est garanti pour un comportement particulier dans lesquels ces deux hypothèses sont tenues. " Dans quels cas, il n'y aura pas de pile alloué? Je veux comprendre cela de manière plus détaillée.
@Sourodepbasu, il n'y a pas beaucoup plus à dire. La pile d'appel est un concept de mise en œuvre, pas un concept de langue C. Il est possible de créer une implémentation C conforme qui ne s'appuie pas sur une pile d'appels. Il est encore plus possible et plausible parmi les implémentations de matériel de produits de base pour y avoir une pile d'appels, mais VLAS ne doit pas être alloué là-bas. Rien de tout cela n'est vraiment motivé par le code source C impliqué
Ils s'appellent Array de longueur variable ou VLA, car
Les tableaux de longueur variable sont une caractéristique optionnelle de la norme ISO C et peut donc ne pas fonctionner sur certains compilateurs.
Souhaitez-vous afficher le code qui compile sans erreurs?
L'avez-vous essayé avec n = 10000000?
Si l'utilisateur entre dans un très grand nombre dans
stdin code>, votre programme est susceptible de planter en raison d'un Overflow de pile .
Ce code permet également des nombres négatifs comme entrée. Attention avec ça ...
@PMG, Andreas Wenzel Merci, je n'étais pas au courant de cette fonctionnalité en C. Comme Stark a souligné qu'il est obligé d'échouer pour le grand n. Même Malloc () est également obligé d'échouer pour une très grande demande d'allocation. Mais il retournera un pointeur nul. Mais la fonction de réseau variable de longueur manipulée dans le compilateur? Y a-t-il un moyen de l'utiliser en toute sécurité. Quelqu'un peut-il expliquer ces questions?
Non, il n'y a aucun moyen d'utiliser la VLA en toute sécurité. Autre que dans les programmes de jouets, je préférerais
MALLOC () CODE> et des amis ... Pour une raison quelconque, il a été changé de requis en C99 pour En option dans C11