Ne peut pas prendre l'adresse de l', obtenir la taille d', ou de déclarer un pointeur vers un type géré
J'ai fait un peu juste de la recherche, mais je suis coincé maintenant pourquoi je suis encore en train cette erreur. J'ai une struct avec les attributs suivants:
struct Account
{
//private attributes
private double mBalance;
private int mAccountNumber;
private string mName;
private string mDateCreated;
}
et suis en train de faire ce qui suit:
class BankManager
{
//private attributes
private unsafe Account *mAccounts;
private unsafe bool *mAccountsAvailable;
private int mNumberAccounts;
}
Même après l'activation de mon Compte à une structure, à l'aide de "dangereux" pour les attributs dans la classe BankManager, et d'indiquer au compilateur qu'il peut utiliser le code unsafe (dans propriétés -> Build), je suis toujours cette erreur au
*mAccounts
Toutes les idées pour lesquelles? Je suis sûr que tous les types que j'utilise dans la structure sont légal d'avoir des pointeurs en c#. Merci à l'avance!
Pourquoi voulez-vous d'utiliser des pointeurs? Il ressemble à
Cela peut aider: stackoverflow.com/questions/2559384/...
BankManager
aura un Collection
de Account
s.Cela peut aider: stackoverflow.com/questions/2559384/...
OriginalL'auteur SantasNotReal | 2012-11-08
Vous devez vous connecter pour publier un commentaire.
Les chaînes dans la classe de Compte l'origine de ce problème. Pour comprendre pourquoi, vous devez comprendre comment le garbage collector œuvres. Il découvre des ordures par le suivi des références à des objets. Le mName et mDateCreated sont ces références. Le mBalance et mAccountNumber sont pas, ces champs sont des types de valeur. Et, plus important encore, la BankManager.mAccounts champ n'est pas, il est un pointeur.
Sorte que le compilateur peut dire que le garbage collector jamais être en mesure de voir la chaîne de références. Parce que la seule façon de le faire est de passer par la mAccount champ et ce n'est pas une référence.
Le seul remède pour cela est de se limiter strictement à des types de valeur. La seule façon de le faire que pour les chaînes de est à les allouer non géré de la mémoire avec, disons, le Maréchal.StringToCoTaskMemUni() et stocker le IntPtr dans le domaine. Il est maintenant hors de la portée de la collecte des déchets ne peuvent être ému. Vous allez maintenant ont également la charge de la libérer de cette chaîne.
Clairement c'est pas pratique et enclins à provoquer des fuites, le genre de problème qui est si commun dans les programmes en C. Pas sûr de savoir pourquoi vous êtes la poursuite de ce mais ne gardez à l'esprit qu'une référence à un objet déjà d'un simple pointeur de sorte que vous ne pas gagner quoi que ce soit par vous-même en utilisant les pointeurs.
OriginalL'auteur Hans Passant
Chaînes de caractères sont des types référence .NET et sont non-blittable pour struct pointeurs. Voir Blittable et Non Blittable Types pour une liste des types de valeur pour ce que vous voulez faire.
Sauf si vous avez des exigences d'affaires, vous devriez coller avec la gestion de la mémoire pour la maintenabilité et de la générale de santé mentale.
OriginalL'auteur hyru
Utilisation
private unsafe fixed char mName[126];
Les chaînes sont gérés types, et sont donc non-fixe tableaux.
OriginalL'auteur avishayp
Vous êtes dans l'erreur à propos de la structure contenant les types qui peuvent avoir des pointeurs, car un
string
est géré type qui ne peut pas avoir un pointeur de référence.OriginalL'auteur Xint0
De données gérée de ne pas rester à un endroit fixe, comme la copie collecteur peut bouger les choses. C'est vrai aussi de la gestion de la boîte de types de valeur. Géré "unboxed" types de valeur ne peut vivre que sur la pile ou à l'intérieur d'autres objets. Ils n'ont que des emplacements fixes si ils sont dans la pile.
Afin de créer un segment de mémoire allouée struct qui a un emplacement fixe à partir de laquelle vous pouvez prendre un pointeur qui continueront à être valides, vous devez allouer dans non géré de la mémoire. Cependant, une fois que vous allouer en mémoire non managée, vous ne pouvez pas mettre géré pointeurs en plus (aka, vous ne pouvez pas utiliser des chaînes de caractères), parce que le garbage collector ne savez pas à propos de ces pointeurs afin de ne pas mettre à jour lorsqu'il se déplace des objets gérés autour pendant la compression.
Par exemple, c'est valide (pas forcément bonne) chose à faire:
Ici, nous avons affecté la structure dans une mémoire non managée. Cela nous permet de tenir un pointeur qui, nous le savons ne pas les modifier ou les déplacer. Nous avons manuellement gratuit la struct lorsque nous avons terminé avec elle. Le même manuel alloc/libre et de l'ordonnancement devra être effectué à mAccounts->mName, car il est de savoir comment un non géré char* c chaîne de style).
J'ai fait la struct ont emballé séquentielle disposition pour rendre le comportement de ce code de plus près, c'est C-homologue, parce que le code ci-dessus ne serait normalement utilisée lorsque vous effectuez l'interopérabilité avec les native C DllImport point d'entrée qui s'attend à un particulier de la structure de mise en page.
OriginalL'auteur David Jeske