9
votes

Est-il une bonne pratique pour initialiser la matrice en C / C ++?

J'ai récemment rencontré un cas où j'ai besoin de comparer deux fichiers (dorés et attendus) pour la vérification des résultats des tests et même si les données écrites aux deux dossiers étaient identiques, les fichiers ne correspondent pas.

sur une enquête plus poussée, j'ai constaté qu'il existe une structure contenant des entiers et un tableau de charcuterie de 64 octets, et tous les octets de la matrice de caractère étaient utilisés dans la plupart des cas et les champs inutilisés de la matrice contiennent au hasard. les données et qui causaient l'inadéquation.

Cela m'a amené à poser la question de savoir s'il est une bonne pratique d'initialiser le tableau en C / C ++, comme cela se fait en Java?


0 commentaires

8 Réponses :


1
votes

Si vous n'initialisez pas les valeurs dans une matrice C ++, les valeurs peuvent être n'importe quoi, il serait donc une bonne pratique de les éjecter si vous voulez des résultats prévisibles.

Mais si vous utilisez le tableau de caractères de caractère comme une chaîne terminée NULL, vous devriez pouvoir l'écrire dans un fichier avec la fonction appropriée.

Bien que en C ++, il pourrait être préférable d'utiliser une solution plus de OOP. C'EST À DIRE. vecteurs, chaînes, etc.


1 commentaires

Non, si vous accédez à une mémoire ininitialisée, vous avez un bogue dans votre programme. Les variables d'initialisation systématiquement génèrent souvent des accès sans écriture inutiles.



23
votes

Il est une bonne pratique pour initialiser la mémoire / les variables avant de les utiliser - les variables non initialisées sont une grande source de bogues souvent très difficiles à parcourir.

Initialisation de toutes les données est une très bonne idée lorsque vous l'écrivez à un format de fichier: il conserve le contenu du contenu du fichier nettoyant afin qu'ils soient plus faciles à travailler, moins enclin aux problèmes si une personne tente de "utiliser" les données non initialisées ( N'oubliez pas que ce n'est peut-être pas simplement votre propre code qui lit les données à l'avenir) et rend les fichiers beaucoup plus compressibles.

La seule raison de ne pas initialiser les variables avant de les utiliser est dans des situations critiques de performance, où l'initialisation est techniquement "inutile" et encourt une surcharge importante. Mais dans la plupart des cas, les variables d'initialisation ne causeront pas de préjudice significatif (surtout s'ils ne sont déclarés que immédiatement avant leur utilisation), mais vous économiserons beaucoup de temps de développement en éliminant une source commune de bugs.


3 commentaires

Quelques indices qui vont dans la même direction: utilisez la plus petite portée possible pour vos variables. Initialiser directement après la déclaration. Utilisez des variables uniquement à un seul but. Utilisez Const si vous avez l'intention de votre variable de ne pas modifier la valeur. La principale raison de ces astuces: ils améliorent la lisibilité et réduisent la chance de subtiles bugs pendant les changements de code. Le code peut être bugfree maintenant, sans suivre ces conseils - mais les suivants, il est plus facile de le garder sans bug avec chaque changement de code.


Définissez et initialisez dans une déclaration chaque fois que possible.


Non, initialisez votre variable où elle convient. A Pour une boucle est plus lisible lorsque la variable de boucle est initialisée dans la déclaration pour. Votre variable a peut-être été déclarée avant la boucle.



6
votes

L'utilisation d'une valeur non définie dans une matrice entraîne un comportement non défini. Ainsi, le programme est libre de produire des résultats différents. Cela peut signifier que vos fichiers se retrouvent légèrement différents ou que le programme se bloque, ou le programme format votre disque dur, ou que le programme provoque des démons de voler le nez des utilisateurs ( http://catb.org/jargon/html/n/nasal-demons.html )

Cela ne signifie pas que vous Besoin de définir vos valeurs de matrice lorsque vous créez la matrice, mais vous devez vous assurer d'initialiser toute valeur de matrice avant de l'utiliser. Bien sûr, le moyen le plus simple de faire cela est de le faire lorsque vous créez la matrice. P>

MyPODStruct bigArray[1000] = { 0 };


2 commentaires

+1 au raccourci, j'utilise ce style un montant équitable. Un mot de prudence sans preuve spécifique de celui-ci, mais je crois que le format = {0} peut être optimisé beaucoup comme la zéromémorique Win32 ( msdn.microsoft.com/en-us/library/aa366920%28vs.85%29.aspx ) API, sous réserve des désirs des compilateurs et paramètres d'optimisation.


Il ne peut être optimisé que si le compilateur peut prouver qu'il ne fera pas une différence observable (c'est-à-dire que toutes les valeurs sont métalliques de toute façon). Dans ce cas, le tableau étant écrit dans un fichier, il ferait certainement une différence observable.



0
votes

Tout d'abord, vous devez initialiser les tableaux, les variables, etc. Si ce n'est pas le cas, vous gênerez la correction de votre programme.

Deuxièmement, il semble que dans ce cas particulier, l'initialisation de la matrice n'a pas affecté l'exactitude du programme d'origine. Au lieu de cela, le programme destiné à comparer les fichiers ne connaît pas assez de suffisamment sur le format de fichier utilisé pour indiquer si les fichiers diffèrent de manière significative ("significatif" défini par le premier programme).

Au lieu de se plaindre du programme d'origine, je corrigerais le programme de comparaison pour en savoir plus sur le format de fichier en question. Si le format de fichier n'est pas bien documenté, vous avez une bonne raison de vous plaindre.


0 commentaires

4
votes

Je suis fortement en désaccord avec les opinions données qui le font "éliminer une source commune de bugs" ou "ne le faisant pas pour gâchera la correction de votre programme". Si le programme fonctionne avec des valeurs unialisées, il a un bogue et est incorrect. Initialiser les valeurs n'élimine pas ce bogue, car ils n'ont souvent pas encore les valeurs attendues à la première utilisation. Cependant, lorsqu'ils contiennent des déchets aléatoires, le programme est plus susceptible de se bloquer de manière aléatoire à chaque essai. Toujours avoir les mêmes valeurs peut donner un comportement plus déterministe dans le collision et facilite le débogage.

Pour votre question spécifique, il s'agit également d'une bonne pratique de sécurité pour écraser les pièces inutilisées avant qu'elles ne soient écrites dans un fichier, car elles peuvent contenir quelque chose d'une utilisation précédente que vous ne souhaitez pas être écrit, comme des mots de passe.


1 commentaires

+1. J'ai vu que les gens croyaient simplement que l'initialisation d'une variable résout tous les problèmes. Non ... cela aide simplement lorsque vous initialisez ce pointeur à NULL à NULL qu'un kaboom toujours au lieu de ne voir que la récolte de la question ici et là et de tirer vos cheveux en essayant de le suivre. Il existe également les scénarios où vous déboguez et exécutez le même blob à plusieurs reprises, et si vous avez une faille logique, vous risquez de descendre des chemins inattendus car la variable / la matrice / etc. arrive à la liquidation de la même mémoire, en utilisant la valeur précédente.



0
votes

Je dirais que la bonne pratique en C ++ utilise un std :: vecteur <> au lieu d'un tableau. Ceci n'est pas valable pour C, bien sûr.


0 commentaires

1
votes

Gardez à l'esprit que la conservation des matières non simplisées peut avoir des avantages tels que la performance.

Ce n'est que mal lire des tableaux non initialisés. Les avoir autour sans jamais lire d'endroits ininitialisés va bien.

En outre, si votre programme a un bogue qui le rend lut par une place ininitialisée dans la matrice, alors "le revêtement" en initialisant de manière défensive toute matrice à la valeur connue n'est pas la solution pour le bogue et ne peut que la rendre surface plus tard.


0 commentaires

1
votes

On pourrait écrire un gros article sur la différence entre les deux styles que l'on peut rencontrer, des personnes qui initialisent des variables toujours lors de leur déclaration et des personnes qui les initialisent si nécessaire. Je partage un grand projet avec une personne qui se trouve dans la première catégorie et je suis désormais définitivement plus du deuxième type. Toujours initialiser les variables a apporté des bugs et des problèmes plus subtils que non et je vais essayer d'expliquer pourquoi, se souvenir des cas que j'ai trouvés. Premier exemple:

struct NODE Pop(STACK * Stack)
{
  if(Stack && Stack->stackPointer)
    return Stack->node[--Stack->stackPointer];
  return EMPTY_STACK;
}


0 commentaires