Puis-je attribuer un nombre de bits en C?
Je suis en train de stocker une grande quantité de booléens de l'information qui est déterminé au moment de l'exécution. Je me demandais quelle est la meilleure méthode pourrait être.
J'ai été essayer d'allouer de la mémoire à l'aide de:
pStatus = malloc((<number of data points>/8) + 1);
en pensant que cela va me donner assez de bits pour travailler avec. Je pourrais alors faire référence à chaque valeur booléenne à l'aide du pointeur dans la notation de tableau:
pStatus[element]
Malheureusement, cela ne semble pas fonctionner très bien. Tout d'abord, j'ai de la difficulté à l'initialisation de la mémoire de la valeur de l'entier 0
. Cela peut être fait en utilisant memset()
? Pourtant, je ne pense pas que l'impact est pourquoi je plantage lors de l'accès pStatus[element]
.
Je suis également pas tout à fait convaincu que cette approche est le meilleur à utiliser. Ce que je veux vraiment, c'est essentiellement un géant masque de bits qui reflète l'état de l'valeurs booléennes. Ai-je raté quelque chose?
- Comment grand est grand? Un million de bits, qui est stocké par octet est à seulement 1 mo de mémoire. Pourquoi perdre son temps avec les bits lorsque octets travail tellement mieux?
- Je pense que les commentaires sont un peu des citoyens de deuxième classe à l'heure actuelle. Mais, cela devient hors sujet pour cette question 😛
- Je suis d'accord avec le commentaire ci-dessus. Il va être beaucoup plus simple et plus rapide (à la fois de dev et de l'exécution) de l'utilisation d'un tableau d'octets (unsigned caractères).
- Je voudrais vous donner le crédit Lott, mais vous n'avez pas de réponse pour moi de vérifier. Merci pour votre suggestion. Il est facile d'oublier que, tandis que 100 000 points de données est beaucoup pour un homme, l'ordinateur ne sont même pas casser une sueur.
- Plus hors-sujet: "convertissez-commentaire(s) de répondre" peut-être la bonne SI caractéristique.
- Il serait mieux de ne pas assumer un octet est toujours 8 bits: certaines très anciennes plates-formes avaient 9 bits/octets, et je crois que le VAXes' (et Nintendo64?) le plus petit entier qui est en 32bits. Préférable d'inclure<limites.h>, et l'utilisation de la macro CHAR_BITS qui garantit la bonne quantité de bits par octet, sur chaque plate-forme.
- Pas tellement pour le Vax. Les caractères de 8 bits. Et de noter que la plupart des implémentations ci-dessous fonctionne très bien avec n'importe quel nombre de bits par octet tant qu'il y a 8 ou plus 🙂
- Bon. Le Point est: pourquoi sacrifier la portabilité à l'aide d'une valeur codée en dur quand vous pouvez faire la bonne chose, dès le début, à presque zéro coût? Vous n'avez qu'à écrire un peu plus, c'est elle!
- Vrai. OP utilisé 8 bits, mais en utilisant CHAR_BITs est la bonne Réponse.
- Ah, trouvé, sur la page Wikipedia de l'Octet de l'article: L'octet le plus souvent constitué de 8 bits dans les systèmes modernes, cependant, la taille d'un octet peut varier et est généralement déterminé par le sous-jacent système d'exploitation d'ordinateur ou de matériel. Historiquement, les octets ont varié de cinq à douze bits. Citation nécessaire?
Vous devez vous connecter pour publier un commentaire.
Ce n'allouer suffisamment d'octets pour votre bits. Cependant,
Ce accède à l'élément th octet, pas peu. Ainsi, lorsque l'élément est plus qu'un huitième du nombre total de bits, vous êtes accédant à la fin du tableau alloué.
Je voudrais définir quelques fonctions d'assistance
(contrôle d'erreur sur la portée de l'élément à gauche pour plus de clarté. Vous pouvez faire ce macros, trop)
...en pensant que cela va me donner assez de bits pour travailler avec. Je pourrais alors faire référence à chaque valeur booléenne à l'aide du pointeur dans la notation de tableau:
élément est de s'attaquer aux octets, pas de bits. Vous voulez quelque chose comme:
Petit point: pour obtenir suffisamment de mémoire pour stocker les N bits (N/8) + 1 octets est imprécise (peut-être un de trop).
(N+7)/8 est toujours le nombre minimum, si.
Bien, la réponse la plus simple serait d'utiliser calloc à la place de malloc.
Il est défini à l'initialisation de la mémoire qu'elle alloue à zéro, et peuvent souvent le faire en utilisant la page de la cartographie des tours.
Qui va prendre soin de votre problème d'initialisation de la mémoire. La douzaine de posts ici semblent répondre de manière adéquate aux indexation problème et le fait que vous, à l'occasion d'allouer un octet supplémentaire (oh l'horreur!), donc, je ne vais pas répéter leur contenu ici.
pStatus[élément] vous donnera un octet entier à cette adresse.
Pour définir un élément particulier que vous feriez quelque chose comme:
À réinitialiser un élément:
et de tester un élément:
l'allocation initiale doit être
ce que vous aviez va fonctionner, mais les déchets de un octet parfois
Je ne peux pas aider mais noter que toutes les réponses dans C ici semblent partir du principe qu'un octet de 8 bits. Ce n'est pas nécessairement vrai dans C (étant entendu qu'il pourra être true sur la plupart des grands de matériel), afin de faire de cette hypothèse dans le code est plutôt une mauvaise forme.
La bonne façon d'écrire de l'architecture neutre code est à
et ensuite utiliser le
CHAR_BIT
macro où vous en avez besoin "le nombre de bits dans unchar
".Vous rendre plus heureux et définir un type et les fonctions de fonctionner sur ce type. De cette façon, si vous découvrez que peu accès sont trop lent, vous pouvez modifier l'unité de mémoire par boolean byte/word/long ou d'adopter des sparse/dynamique des structures de données si la mémoire est vraiment un problème (c'est à dire, si vos jeux sont pour la plupart des zéros, vous avez juste à garder une liste avec les coordonnées de la 1.
Vous pouvez écrire votre code afin d'être complètement à l'abri des changements apportés à la mise en œuvre de votre vecteur de bits.
pStatus[élément] n'est pas de l'adresse de bit. L'octet exact c'est dépendante du type de pStatus -- je suppose char* ou équivalent -- donc pStatus[élément] devient l'élément ième octet.
Vous pourriez memset à la valeur 0, oui.
Qu'une partie de l'amende.
voici où vous avez des problèmes. Vous êtes octets d'adresse, quand vous voulez bits de l'adresse.
permettra d'obtenir le droit d'octets dans le tableau.
Vous avez besoin d'allouer
c = malloc((N+7)/8)
octets, et vous pouvez définir le nième avecclair avec
et de tester avec
Si vous n'avez pas l'esprit d'avoir à écrire des wrappers, vous pouvez également utiliser les deux bit_set ou bit_vector de C++STL, semble qu'ils (surtout le second) exactement ce dont vous avez besoin, déjà codé, testés et emballés (et beaucoup de cloches et de sifflets).
C'est une véritable honte qui nous manque, un simple moyen d'utiliser du code C++ dans des applications C (n, la création d'un wrapper n'est pas à moi, ni plaisir, et signifie plus de travail à long terme).
Ce serait mal avec
std::vector<bool>
?Cela m'étonne qu'une seule réponse ici mentionne CHAR_BIT. Un octet est souvent 8 bits, mais pas toujours.
Vous de répartition de code est correct, voir la
set_bit()
etget_bit()
de fonctions données dans cette réponse pour accéder à la valeur de type boolean.Si vous êtes limité à seulement quelques bits, vous pouvez au lieu de eaanon01 solution aussi utiliser le c builtin installation de champ de bits (il y a très peu d'occasions où vous pourriez utiliser, mais ce serait une)
Ce bit banging je peux recommendate:
Herny Warrens Hacker "Plaisir"
Le booléen est "jamais" une valeur distincte dans C. Donc, une structure peut être pour vous d'aller.
Il est vrai que vous n'initialisez pas le mem région de sorte que vous besoin de le faire individuellement.
Voici un exemple simple de la façon dont vous pourriez le faire avec les syndicats, les structures et les énumérations,
Espère que cette aide. Cet exemple peut gérer jusqu'à 64 état des booléens et pourrait être facilement étendu.
Ce exapmle est basé sur le Char = 8 bits int = 16 bits de long int = 32 bits et long long int = 64 bits
J'ai maintenant également ajouté le support pour les groupes de statut.