Accéder à un tableau avec un nombre négatif!
Je suis de la conversion d'un extrêmement grand et très vieux (25 ans!) programme de C à C++.
En elle il ya beaucoup de (très très nombreux) des endroits où j'ai accès global dimensions UBYTE tableau à l'aide d'une variété de integer index. Parfois cet indice peut être négatif.
J'ai parfois, mais pas toujours, pris au piège de ce cas et a fait en sorte que rien ne s'est passé, mais comme une ceinture et bretelles mesure j'ai effectivement pris la peine de faire en sorte qu'il y avait une autre partie de la mémoire qui précède immédiatement le tableau et l'a rempli avec le droit des valeurs telles que, si j'ai involontairement omis de piéger le nombre négatif condition, alors une réponse correcte serait encore récupéré dans le tableau. En fait, cela a bien fonctionné pendant de très nombreuses années.
Mais maintenant sous C++, il semble que l'accès à un tableau avec un nombre négatif se comporte différemment et maintenant, j'ai un programme comporte mal. Je fixe un cas de non gérée nombre négatif et le programme semble fonctionner très bien, mais je suis nerveux que je n'ai pas piégé tous les nombres négatifs et il peut y avoir des problèmes à l'avance.
Donc ma question maintenant, est-il possible, au moment de l'exécution, pour moi, pour détecter toutes les instances de l'accès à des tableaux avec des index négatifs? Je vais être impressionné si quelqu'un peut venir avec une réponse. Si vous êtes à peu près certain qu'il ne peut pas être fait de toute façon automatisée ensuite me dire que l'information est précieuse, trop.
Je voudrais juste ajouter que je ne suis pas vraiment un programmeur C++ (encore). Jusqu'à présent tout ce que j'ai fait est la valeur absolue de minimum (presque rien) pour obtenir le programme à compiler sous un compilateur C++. Donc, si votre réponse implique de fantaisie "experts seulement, C++ solutions", alors s'il vous plaît essayer de l'expliquer par des mots d'une syllabe ou me donner un lien afin que je puisse le regarder.
Si ça fonctionne, ne pas la toucher.
Si cela fonctionne, l'améliorer.
Rappelez-vous, que dans le C et le C++, le tableau d'indexation obéit à un[i] = *(a + i), c'est juste un simple calcul des adresses, rien de fantaisie. Si i est négatif, vous aurez accès à la mémoire avant que le tableau commence. Bien sûr cela peut changer en C++ avec une surcharge de l'opérateur[](), mais c'est le cas de base.
Négatif indices sont autorisés, mais aller à l'extérieur des limites du tableau n'est pas. Donc, si vous utilisez un indice négatif sur le début du tableau, c'est mauvais, mais si vous avez un pointeur p vers le troisième élément, alors p[-2] est parfaitement légal.
OriginalL'auteur Mick | 2009-09-14
Vous devez vous connecter pour publier un commentaire.
Pouvez-vous remplacer le mondial-dimensions ubyte tableau avec un objet avec la surcharge de l'opérateur[]? En utilisant la valeur absolue de l'entrée int peut résoudre certains de vos problèmes.
Edit: en Fonction du modèle d'utilisation de votre tableau (pas de pointeur manigances), à l'aide d'un objet avec la surcharge de l'opérateur[] pourrait effectivement être totalement transparent pour les utilisateurs de la matrice, d'où ma suggestion.
Votre commentaire est correct - si j'étais sous l'impression que l'application d'origine a "piraté" autour de l'indice négatif question par la mise en miroir de la matrice en mémoire autour de 0 - donner le genre de comportement avec des index négatifs qui, en valeur absolue, pourrait faire aussi bien.
comme je comprends la question, la version originale du programme piraté autour d'elle, mais maintenant, il veut être averti lorsque des indices négatifs se produire, de sorte qu'il peut effectivement fix le programme. Ce qui sonne comme la bonne façon de faire. Et puis, bien sûr, une exception serait correct (même si l'exploitation forestière, et probablement de tir une assertion pourrait être utile également)
+1 Pour la suggestion de remplacer le tableau avec un objet et l'opérateur[]. C'est un bon moyen de garder la trace.
OriginalL'auteur Joris Timmermans
Connaissez-vous les limites des indices?
À lire le commentaire sous Siyfion réponse, il semble que négatif indices sont permis dans votre domaine de problème, et donc il ne sert à rien d'essayer de forcer tous les indices positifs. Une meilleure solution est de permettre négative des indices sans enfreindre les règles de la langue (qui de C de la version aussi ne btw. Vous avez simplement eu de la chance il n'a pas explosé ;))
Donc, si vous savez que les indices que vous allez utiliser sont dans la plage de -x à y, il suffit de créer un tableau de taille x+y, et l'utilisation d'un pointeur vers le xème élément lors de l'accès au tableau.
Par exemple, si vous avez besoin d'un tableau avec des indices de -4 à 5:
Cours de la même chose pourrait (et devrait) ont été réalisées dans le C.
Un autre conseil serait de ne pas accéder au raw tableau directement. Définir de simples fonctions d'accesseur à la place. (par exemple, mais pas nécessairement, en mettant le tableau dans une classe. Si vous ne le mettez dans une classe, vous pouvez surcharge de l'opérateur[] de sorte que vous pouvez même look comme un tableau encore)
La charge de cette est précisément zéro (pas de "près de zéro, ou la "si proche de zéro, vous ne remarquerez pas la différence", mais zéro. Le code généré sera exactement le même que si vous voulez accéder au tableau), comme le compilateur inline court fonctions, mais il vous permet également d'insérer des contrôles supplémentaires de sorte que vous pouvez vérifier dans les versions de débogage que vous n'avez jamais dépasser les limites du tableau.
OriginalL'auteur jalf
Une sorte de l'utilisation de la mémoire vérificateur peut travail, en particulier si vous pouvez forcer le tableau à sa propre page. Je voudrais utiliser
valgrind
sur Linux, vous ne savez pas ce que vous souhaitez utiliser sur Windows -purify
?OriginalL'auteur Douglas Leeder
L'envelopper. En alternative, vérifiez si votre compilateur prend en charge la vérification de limite.
Pire des cas, je ne voudrais pas mettre les valeurs valides dans votre tableau de nombres négatifs. Je mettrais ouvertement mal valeurs, de sorte que vous obtenez une manifestement erronée de la valeur lorsque cela se produit. Vous n'aurez pas à cerner le problème sans un débogueur, mais au moins vous avez un avertissement clair que quelque part, un peu de code est de le faire.
Aucune idée, jamais utilisé, VS, mais si elle n'en a pas, microsoft a un problème.
Le problème est que C et C++ par extension) certainement permettre d'index de tableau avec un indice négatif, tant que vous n'avez pas réellement la forme d'un index près de l'array (!). Par conséquent, vous ne pouvez pas tout simplement des limites des contrôles, pas dans Visual C++, ni dans d'autres compilateurs C/C++.
Depuis j'imagine que ça va faire négative de l'arithmétique des pointeurs, cela sera permis parce que vous êtes en pointant sur un arbitraire vmem zone. Tant que le compilateur ne fournit pas de precode pour vérifier cela comme une inhabituelle d'exécution problème. Je me souviens que le IBM compilateur C sur la sp4 a cette case.
OriginalL'auteur Stefano Borini
Remplacer votre tableau global par std::vector. Remplacer l'utilisation de la
array[index]
la syntaxe parC'est exactement ce que vous demander: il ajoute runtime tableau lié contrôles.
OriginalL'auteur Wim Coenen
la seule façon que je peux penser serait pour envelopper le tableau dans une méthode qui vérifie l'indice est positif.
OriginalL'auteur wefwfwefwe
Personnellement, j'essaierais de faire le tri pourquoi l'un de vos indices pourraient jamais être négatif; il est évident qu'ils seront de retour une valeur incorrecte alors certes, vous ne devriez pas laisser l'indice est négatif?
Corriger le code qui leur permet d'aller négatifs plutôt que d'essayer de faire une prise carrée s'insérer dans un trou circulaire (façon de parler) 😉
Une des belles choses sur le C++, c'est que les compilateurs de l'inclure de façon très agressive. Tant que tout est visible par le compilateur, de petites fonctions de obtenir inline, si bien que la surcharge est exactement zéro. Ne vous inquiétez pas trop à propos de l'enroulant dans les appels de fonction (tant que la totalité des définitions de fonction, et pas seulement des déclarations, sont visibles)
Par ailleurs, cette information doit figurer dans la question, où tout le monde le voit, et non pas dans un commentaire. La question donne l'impression que négatif les indices sont des erreurs qui doivent être corrigées. Si le résultat est négatif indices sont permis dans votre domaine de problème, laissez-nous le savoir. Que les changements de la solution complètement. 🙂
Je vois bien ce que vous dites il n'y Mick, mais comme jalf.com dit, la plupart des petites "l'habillage" des fonctions sera tout simplement obtenir fait pour être en ligne avec peu (voire pas du tout) notable sur les performances. Si l'accès au tableau avec des nombres négatifs sens, peut-être vous devriez créer un deuxième "négatif" de tableau, et il suffit de passer qui est accessible?
OriginalL'auteur Siyfion
Une chose que vous pouvez faire est que vous pouvez vérifier jusqu'à quelle valeur minimale de votre index et commencer à remplir votre tableau à partir de l'indice.
un[-i] = *(a - i)
donc de commencer avec (a-i) ainsi que votre adresse de base au lieu de (a) si vous venez de changer votre tableau et d'obtenir des valeurs de votre choix.
OriginalL'auteur GG.
Regardez cet exemple par le MSDN:
Positifs et Négatifs des Indices
OriginalL'auteur Magnetron