Est-il prudent de lire après la fin d’un tableau?

Disons que j’ai un constructeur comme celui-ci:

MyColor(uint8 vec[]) { r = vec[0]; g = vec[1]; b = vec[2]; a = vec[3]; } 

Mais je l’appelle comme ça (3 éléments au lieu de 4):

 uint8 tmp[] = {1,2,3}; MyColor c(tmp); 

Mais maintenant vec[3] n’est pas défini … est-il prudent d’affecter cette valeur à a ? Si ce n’est pas le cas, il n’y a pas de solution de rechange intéressante pour vérifier si vec[3] est défini.

Si vous ne voulez pas utiliser de vecteur, essayez ceci …

 MyColor(uint8 (&vec)[3]) { r = vec[0]; g = vec[1]; b = vec[2]; } MyColor(uint8 (&vec)[4]) { //... } uint8 a1[] = {1,2,3}; MyColor c1(a1); uint8 a2[] = {1,2,3,4}; MyColor c2(a2); uint8 a3[] = {1,2,3,4,5}; MyColor c3(a3); // error 

vous n’avez pas à inclure explicitement la taille du tableau et si vous essayez de passer un tableau avec un nombre incorrect d’éléments, une erreur de compilation sera générée,

Non ce n’est pas sûr. C’est un comportement indéfini tel que défini par la norme. Cela pourrait faire exploser toute l’application ou renvoyer une valeur aléatoire. La solution consiste à passer la taille avec elle ou à utiliser vector .

Non, ce n’est pas sécuritaire. Vous lisez une mémoire que vous n’avez pas allouée et il s’agit d’un comportement non défini. Selon la phase de la lune, il est possible que vous obteniez ou non une erreur de segmentation.

Pour “contourner” cela, assurez-vous que le tableau que vous avez passé a toujours la bonne taille. Dans votre exemple, vous pourriez faire:

 uint8 tmp[4] = {1,2,3}; MyColor c(tmp); 

L’initialiseur n’a pas besoin de spécifier tous les éléments du tableau qui est créé. Il est donc correct d’initialiser explicitement les trois premières valeurs. Les valeurs restantes seront mises à zéro.

Non, ce n’est pas sécuritaire. Vous voudrez peut-être transmettre les coordonnées en tant que parameters au constructeur et utiliser deux surcharges:

 MyColor(uint8 a, uint8 b, uint8 c, uint8 d) { stuff } MyColor(uint8 a, uint8 b, uint8 c) { stuff } 

De cette façon, vous pouvez utiliser les deux

 MyColor a(1, 2, 3); MyColor b(1, 2, 3, 4); 

En C ++, comme en C, les tableaux d’arguments de fonction se décomposent en pointeurs. Maintenant, en fonction de la sémantique de la fonction, vous pouvez utiliser d’autres approches:

 // explicit parameters (with or without default values): mycolor( uint8_t r, uint8_t g, uint8_t b, uint8_t alpha = 255 ); // vector (can check length) mycolor( std::vector const & components ); // array by reference mycolor( uint8_t (&components)[ 4 ] ); 

La première approche à moi est la plus propre.

Nan. Il est possible que cela cause une erreur de segmentation.

Billy3

Le comportement présenté n’est pas défini et risque de planter.

Je recommanderais d’utiliser vector le long et d’accéder aux éléments en utilisant l’appel vector :: at (). Cela jettera une exception si elle dépasse les limites allouées. Assurez-vous de réserver suffisamment d’espace dans le vecteur

C’est comme si vous demandiez s’il est sécuritaire de construire une maison au dessus d’un lac. Un jour, vous pouvez vous réveiller dans l’eau.

Dans votre cas, vous constaterez peut-être qu’un pointeur suspendu peut être source d’instabilité et de pannes fréquentes du système.

Si vous savez ce qu’est un pointeur en suspens, quel est le risque?