2009-02-22 7 views
2

J'ai récemment vu quelques projets open source qui le font réellement; renvoie un pointeur non sécurisé à partir d'une fonction telle que: "int * input = this.someIterator.GetUnsafePtr()". D'après ce que j'ai compris, cela doit être complètement faux. Les pointeurs non sécurisés ne peuvent être obtenus que via des instructions 'fixed' et certainement ceux qui sont retournés depuis une fonction ne seront plus épinglés (ils perdront leur portée déclarante), ce qui les fera éventuellement être récupérés. Mais je ne me souviens pas non plus que le compilateur ait donné un avertissement à ce sujet, alors pourquoi s'embêter à utiliser une instruction fixe si les pointeurs «épinglés» peuvent être répartis partout?Pourquoi est-il autorisé à renvoyer des pointeurs non sécurisés depuis une fonction?

Répondre

2

Je n'ai jamais vu de telles constructions dans des projets open source. Il vaudra mieux que vous fournissiez quelques exemples d'un tel usage dans votre question. Le sens de cela peut dépendre du comportement.
Mais je suis d'accord, les pointeurs dangereux sont mauvais et ne devraient être utilisés que lorsque vous interagissez avec des bibliothèques ou du code natif. Autant que je m'en souvienne, vous pouvez utiliser cette construction uniquement dans un bloc dangereux. Donc je pense que le compilateur ne donnera aucun avertissement ici. Et IMO, il est préférable d'utiliser IntPtr (les blocs dangereux peuvent être exécutés uniquement en confiance totale).
EDIT:
@Stephen a raison, IntPtr ne conserve pas la référence à l'objet sur la collection GC.

+0

IntPtr n'est pas un pointeur de suivi. Si un IntPtr fait référence à un objet géré et que cet objet est déplacé, le pointeur n'est pas mis à jour. Il n'y a pas de différence réelle entre un IntPtr et un pointeur non sécurisé, si ce n'est qu'un IntPtr est conforme à CLS et n'est pas "dangereux". –

+0

Vous avez raison, merci. Je pense que j'ai encore besoin de lire sur le CLR. – zihotki

3

Que diriez-vous, Marshal.AllocHGlobal ou Marshal.AllocCoTaskMem, à la fois le retour IntPtr, qui peut être librement jeté à void * en utilisant la fonction .ToPointer()?

Ou le pointeur peut provenir d'un code non géré. Vous avez besoin de mémoire fix/pin parce que la mémoire est gérée, donc tant que ce n'est pas fixed/pinned le garbage collector est libre de le déplacer, ce qui rend le pointeur invalide.

Questions connexes