C dynamique struct (malloc et free)
Je suis en train d'apprendre les bases du C, C++ programmation, j'ai donc commencé avec un "C".
J'ai beaucoup d'expérience de la programmation avec Java et VB. Mais "C" est ce que je veux apprendre.
Donc je vais avoir un problème, en essayant de comprendre le "malloc" et de la "liberté" des fonctions.
J'utilise Borland C++ 4.5 et Visual C++ 6.0 sur Windows 98. - (Juste un environnement de test, vous voulez apprendre les principes de base et le début de la programmation sous windows).
Reportez-vous à ce code:
struct String
{
char *value;
int length;
};
char *initString(const char *value)
{
char *str = (char*)malloc( strlen(value)+1 );
strcpy(str, value);
return str;
}
struct String *InitString(const char *text)
{
struct String *str = (struct String*)malloc( sizeof(struct String) );
str->value = initString(text);
str->length = strlen( str->value );
return str;
}
void freeString(struct String *str)
{
free(str->value);
free(str);
str = NULL;
}
int main(int argv, char *argc[])
{
struct String *theString = InitString("Testring string struct");
printf("String: %s\n", theString->value);
printf("String Length: %d\n", theString->length);
freeString(theString);
printf("\nData: %s", theString->value);
return 0;
}
Lorsque ce programme est exécuté, le résultat est correct.
Après j'appelle "freeString(theString)
", la fonction ne libérer de la mémoire et de l'ensemble de la
struct la valeur NULL à l'intérieur de la "freeString ()", qui doit libérer les "theString" à l'intérieur "main()" comme je passe le pointeur sur "theString", mais quand la fonction renvoie: "theString" n'est pas "NULL".
Sur Borland 4.5 je peux toujours appeler le "printf" avec "theString->valeur" et il affiche la chaîne de caractères.
Sur Visual C++ le programme se bloque lors de l'appel de "printf", MAIS "theString" n'est pas "NULL".
Quand je trace le programme en mode debug, le "struct" est libéré à l'intérieur de la "freeString()" la fonction et la structure est définie à NULL, mais quand la fonction renvoie la "theString" n'est pas NULLE, et la "valeur" est encore utilisable sur Borland, mais pas sur Visual C++.
Donc j'essaye de comprendre ce qui se passe ici?
Est-il de la référence qui doit être fait?
Vous en remercie d'avance!
Notez également que les bases de la programmation en C sont très, très différents les bases de la programmation en C++. La syntaxe des langues est très similaire et ils partagent certains détails de bas niveau, mais ils sont encore fondamentalement différentes. Vous devez en choisir un et assurez-vous que vous avez un bon débutant C livre ou une bonne introduction à C++ livre.
Aussi, et quelqu'un crier à moi si je me trompe, mais a quoi bon l'appel de la
free(struct)
faire? C'est un pointeur, oui, mais pas à un allouée dynamiquement l'espace. Il est tard (royaume-UNI), de sorte s'il vous plaît excusez-moi si je me trompe. Je seconde le commentaire pour une plus moderne de compilateur.Je suis en fait à l'aide de Visual Studio 2010. J'utilise C# pour créer des add-ons pour AutoCAD et Revit. Mais C# est le code managé. Donc, je n'ai aucune expérience avec aucun n'avait réussi. J'ai aussi programme 8086 assemblée à l'aide de TASM et ce, à l'aide de DosBox. Je veux juste comprendre le matériel de bas niveau, et la façon dont la mémoire est en cours de manipulation. Eh bien, je suppose que vous pouvez dire que j'ai vraiment aime le défi. Et je suis d'accord que le vieux C et telle est une douleur dans le cul.
OriginalL'auteur Daniel | 2010-12-28
Vous devez vous connecter pour publier un commentaire.
Vous êtes à la recherche à un comportement indéfini (vous êtes en utilisant une valeur après qu'il a été libre avais), donc vraiment quelque chose pourrait se produire. Il pourrait accident, ou il pourrait fonctionner "normalement"
Ce qui est probablement ce qui se passe est msvc, au moins en mode de débogage, des zéros ou écrit un spécial modèle d'octet de la mémoire vous gratuit de sorte que le str->valeur du pointeur devient invalide et se bloquer lorsque vous déréférencement d'elle, tandis que borland juste à libère la mémoire retour à un pool de mémoire, mais laisse intact.
Votre
str=NULL
dans la fonctionn'a pas d'effet réel. Elle ne fait qu'locales
str
valeur NULL, l'appelant n'est pas affectée.Si vous souhaitez définir le pointeur de l'appelant à NULL, vous devez passer un pointeur de pointeur, ou, dans le cas de C++, passer une référence pour le pointeur.
DEADDEADDEAD
viennent...Merci à vous nos. Vous avez une très bonne explication, très claire. J'ai passé 2 bonnes heures sur google et documentations à trouver la réponse que vous avez fournie. Toutes les sources sur google et les autres ont une simple utilisation locale de "malloc" et "libre", mais aucun d'entre eux montrent des problèmes lorsque vous "malloc" dans une fonction et "libre" dans l'autre - le pointeur de référence que vous avez identifiés dans votre post.
OriginalL'auteur nos
C'est une des raisons pour lesquelles vous ne devriez jamais, jamais, utiliser un pointeur après que la mémoire est libérée. Le comportement est indéfini et c'est exactement ce que vous voyez ici.
OriginalL'auteur Otávio Décio
C est appel par valeur. Ce serait se mettre à
NULL
si vous l'avez appeléfreeString(anotherFunction(theString))
?Vous devez passer un pointeur vers un pointeur, si vous voulez avoir une fonction d'effet secondaire sur le référent de ce pointeur.
Idiomatiques C99 serait tout simplement omettre la cession de
str = NULL
dansfreeString()
.OriginalL'auteur jfm3
En fait, qui ont à passer en argument l'adresse du pointeur et pas seulement le pointeur
Sinon, vous définissez la valeur NULL à une copie du pointeur str pas de str...
Et dans main() n'oubliez pas de tester pointeur NULL pour éviter le crash :
OriginalL'auteur Stef
Vous essayez d'accéder à un champ qui est publié. Et que les résultats d'un comportement indéfini. Vous êtes en mesure d'accéder à la valeur en dépit d'être libéré sur certains compilateurs parce que ce domaine n'est pas réinitialisé par une autre application en cours d'exécution. Même sur X du présent Code s'exécute heureusement, mais pas sur le Compilateur Visual Studio.
OriginalL'auteur Mahesh