question assez basique ici, je suis un peu incertaine sur le passage de la mémoire dans C.
Si j'ai le suivant P>
CGPoint *currentTilePosition = tileForCoordinates(curPosition, 50, 50);
5 Réponses :
règle très basique à suivre est si vous renvoyez un * MALLOC * ED POINTER, donnez à l'utilisateur une fonction Passez le pointeur de retour pour libérer ou documenter que vous * malloc * ed et qu'ils doivent libérer. P >
J'ai vu une variété de solutions à cela (y compris une abstraction complète de la gestion de la mémoire) et personnellement, je préfère la méthode gratuite désignée de l'API car il est clairement quoi faire quand il est temps de libérer l'objet et il donne l'API une dernière tentative de travail de nettoyage supplémentaire. P>
Merci. Il est donc préférable de masterner une structure, puis de la configurer en appelant la fonction E.G. CGPOINT * CORRECTTLEPOSITIONNED = TILEFORCOORCATS (CUTPOSITION, 50, 50); ?
@Helium, vous avez demandé si quelque chose est "meilleur" mais je n'ai pas tout de suite attrapé ce que l'autre option est. C'est-à-dire que je ne vois qu'un côté de la question.
Donc, je devrais malcoc une structure, puis la configurer en appelant la fonction par exemple. CGPOINT * CORRECTTLEPOSITIONNED = TILEFORCOORCATS (CUTPOSITION, 50, 50); ? ;)
Pouvez-vous passer à un argument à l'appel de la fonction? De cette façon, l'appelant trouvera plus facilement à mémoriser avec Malloc / CalloC et Gratuit. P>
Donc, créez-le cgpoint Tilecoordinate = (CGPoint i>) MALLOC (Tailleof (CGPoint)); Avant, réglez-le égal à TileForcoordinates (CGPoint * Tilecoord, position CGPoint, largeur courte, hauteur courte)? Comment la fonction reviendrait-elle à regarder?
CGPoint * Tilecoordinate = (CGPoint) MALLOC (Tailleof (CGPoint)); .... INTEGER = TILEFORCOORCORDINATES (position CGPoint, largeur courte, hauteur courte et tilécoordinate); ....
Merci. Donc, si un pointeur est passé et ses données modifiées, il n'est pas nécessaire de le retourner, est-ce correct?
Oui, et l'appelant est libre d'allouer et de détruire l'objet pour le pointeur.
@ VPIT3833: Vous devez utiliser Tilecoordinate, non et Tilecoordinate - sinon, votre paramètre doit être un CGPoint ** - qui est indirecte inutile. De plus, si le Tilecoordinate est scopé localement, vous ne devez pas utiliser MALLOC / GRATUIT du tout - allouez-le sur la pile (alors vous utiliseriez et tileCoordinate comme paramètre).
@Joshua Warner Droite, mon erreur de faute de frappe: D Je voulais dire tilecoordinate
En règle générale, tout ce que vous Donc, en général, le motif ressemble à ceci: P> MALLOC code> Vous devez également gratuit code>. En une autre règle, si votre API effectue l'allocation, votre API devrait également faire la répartition de la transaction, car à un moment donné sur la route, vous pouvez modifier le mécanisme sous-jacent. De plus, sous Windows, si la mémoire est allouée par une DLL, elle doit être libérée par la même DLL ou les mêmes choses qui se produisent. MyType* foo = myapi_dosomething(x,y,z);
if (!foo) die("No Foo!");
use_object(foo);
myapi_free(foo);
foo=NULL; // just in case
Intéressant à propos de la DLL, mais a tourné mon dos sur les fenêtres environ. :( J'ai vu l'utilisation de FOO = NIL; puis [FOO Living]; dans l'OBJ C, n'a pas l'ordre de ces questions?
@ Helium3: Fixer un pointeur sur NULL Une fois que vous avez fonctionné, il s'agit d'une précaution de sécurité, de sorte que si vous essayez de l'utiliser à nouveau, vous obtiendrez un segfault immédiat au lieu d'un comportement indéfini. Je ne sais pas sur l'objectif c - je ne fais pas Apple.
L'appelant devra code> gratuit code> le pointeur Toutefois, si vous emballez sur la fonction MALLOC code> ED par votre fonction. TILEFORCOORDINATES CODE> dans une bibliothèque dynamique, vous devez également fournir une fonction d'accompagnement pour libérer la mémoire et ne pas avoir l'appelant le faire. En effet, l'appelant est peut-être un lien avec l'exécution C de manière différente de celle de votre bibliothèque. Par exemple, si votre bibliothèque se lie statiquement sur le temps d'exécution C, tandis que l'appelant se lie de manière dynamique, ou inversement, que l'appelant libère la mémoire entraînera des accidents. Dans de tels cas, vous pouvez fournir une fonction similaire aux éléments suivants: P> CGPoint *point = tileForCoordinates( ... );
// use point
...
// now free it
freeTileCoordinates( &point );
Je sais que c'est boiteux de demander, mais quel est le double * pour?
@ Helium3: Le double ** est de sorte que la fonction de libération peut prendre un pointeur sur le pointeur d'origine malloc code> ED par votre fonction. Cela permet à la fonction de définir ce pointeur sur NULL après avoir libéré la mémoire. J'ai ajouté un exemple d'utilisation.
Précisément; C ne dispose pas de True Pass par référence, vous devez donc transmettre un pointeur sur le pointeur afin de pouvoir modifier le pointeur d'origine.
Le pointeur déclaré par Toutefois, parce que vous retournez la valeur du pointeur à la fonction d'appel, elle existe maintenant dans le cadre de pile actuel (après son retour). Cette valeur est référencée par la variable la mémoire MALLOC () code> sera une valeur dans le cadre de pile de la fonction d'exécution actuelle. Lorsque le cadre de la pile (et donc * Tilecoordinate code>) dépasse le rendement de la fonction, ce pointeur cessera d'exister. p>
* actuelleTileposition code>. P>
masloc () code> est une histoire complètement différente; La mémoire allouée de manière dynamique existe sur le tas. Vous devriez libérer toute mémoire que vous allouez dans la même implémentation qui effectue une allocation. Cela implique appeler gratuit () code> sur actueltileposition code> dès que vous l'avez fait, généralement dans le même fichier. P>
Dans C, vous n'avez pas besoin de jeter la valeur de retour de
MALLOC code>, et certains (comme moi-même) considèrent comme une mauvaise idée pour un certain nombre de raisons qui peuvent (et la volonté) être débattuellement.Merci, bon à savoir. Cela entraînerait donc de supprimer les deux le pointeur renvoyé de Malloc ainsi que le retour du pointeur pour la fonction?
Je pense que vous pourriez être mal compris -
MALLOC CODE> renvoie AVOID * code> Pointeur, qui peut être implicitement couplé à tout autre type de pointeur. Donccgpoint * x = malloc (taille de (CGPoint)); code> est tout ce dont vous avez besoin. En fait, je suggéreraiscgpoint * x = malloc (taille de * x); code>. Si le type dex code> modifie, la première ligne devra être modifiée deux fois, et si vous oubliez, vous pourriez accidentellement allouer à peu d'espace pour l'objet. Dans la deuxième ligne, letaille de code> s'ajuste automatiquement lorsque vous modifiez le type dex code>.Après certaines des réponses ici, il semble correct de Malloc ce point CGPoint quelque part, puis transmettez-le dans cette fonction pour la manipulation (avec la déclaration CGPoint Tilecoordinate = (CGPoint i>) MALLOC (Tailleof (CGPoint)); Supprimé et les paramètres modifiés). Avez-vous des commentaires ci-dessus s'appliquent à la question initiale avec le malloc dans la fonction? Il est tard :/