Je me demandais pourquoi le code suivant ne fonctionnait pas
int main(int argc, char **argv)
{
char *test = (char*) malloc(12*sizeof(char));
test = "testingonly";
free(test);
}
Après y avoir réfléchi, je partais du principe que j’allouais d’abord de la mémoire pour 12 caractères, mais que l’affectation de la ligne suivante crée un tableau de caractères sur la pile et que son adresse mémoire est testée. Donc free () essaie de libérer de l'espace sur la pile, ce qui n'est pas autorisé. Est-ce exact?
Alors, quelle serait la bonne approche pour enregistrer une chaîne sur le tas? Est-ce que le suivant est un chemin commun?
int main(int argc, char **argv)
{
char *test = (char*) malloc(12*sizeof(char));
strcpy(test, "testingonly");
free(test);
}
char *test = (char*) malloc(12*sizeof(char));
+-+-+-+-+-+-+-+-+-+-+-+-+
test--->|x|x|x|x|x|x|x|x|x|x|x|x| (uninitialized memory, heap)
+-+-+-+-+-+-+-+-+-+-+-+-+
test = "testingonly";
+-+-+-+-+-+-+-+-+-+-+-+-+
test + |x|x|x|x|x|x|x|x|x|x|x|x|
| +-+-+-+-+-+-+-+-+-+-+-+-+
| +-+-+-+-+-+-+-+-+-+-+-+-+
+->|t|e|s|t|i|n|g|o|n|l|y|0|
+-+-+-+-+-+-+-+-+-+-+-+-+
free(test); // error, because test is no longer pointing to allocated space.
Au lieu de changer le pointeur test
, vous devez copier la chaîne "testingonly"
dans l'emplacement attribué à l'aide de, par exemple. strcpy
ou utilisez strdup
. Notez que des fonctions telles que malloc
et strdup
renvoient NULL
si la mémoire est insuffisante, et doit donc être vérifiée.
char *test = (char*) malloc(12*sizeof(char));
strcpy(test, "testingonly");
+-+-+-+-+-+-+-+-+-+-+-+-+
test--->|t|e|s|t|i|n|g|o|n|l|y|0|
+-+-+-+-+-+-+-+-+-+-+-+-+
ou
char *test = strdup("testingonly");
+-+-+-+-+-+-+-+-+-+-+-+-+
test--->|t|e|s|t|i|n|g|o|n|l|y|0|
+-+-+-+-+-+-+-+-+-+-+-+-+
Vous avez déjà répondu à votre question. Strcpy est essentiellement le moyen approprié de copier une chaîne.
La première version ne crée pas de chaîne sur la pile, mais vous avez raison de dire que vous n'êtes pas autorisé à free
après l'affectation. Les littéraux de chaîne sont généralement stockés dans des sections de mémoire constantes/en lecture seule. L'affectation ne copie rien, mais fait simplement que test
pointe sur cette zone de mémoire. Vous ne pouvez pas le libérer. Vous ne pouvez pas non plus modifier cette chaîne.
Votre deuxième morceau de code est correct et habituel. Vous voudrez peut-être aussi regarder dans strdup
si votre implémentation en est dotée.
Eh bien vous avez raison. Voyons maintenant le premier morceau de code.
char *test = (char*) malloc(12*sizeof(char));
Le code ci-dessus n'est pas un problème.
test = "testingonly";
Ici, vous avez modifié le pointeur test
conduisant à une fuite de mémoire. Et lorsque vous essayez de libérer, vous ne libérez pas le pointeur réellement alloué, mais un littéral "testingonly" pointant vers. Les points littéraux indiquent une mémoire constante qui ne peut pas être remplacée dans les scénarios habituels.
En ce qui concerne maintenant le deuxième morceau de code, cela fonctionnera correctement si vous avez explicitement copié les données de l'endroit où le littéral réside dans le tas où votre test
pointe.
Pour votre deuxième point, oui strcpy
est un moyen habituel. Vous pouvez également utiliser "memcpy" si vous copiez des octets bruts.
Remarque: les littéraux ne sont pas stockés sur la pile. Mais vous ne pouvez pas modifier l'emplacement où les littéraux sont stockés.
le code
#include <stdio.h>
int main(int argc, char **argv)
{
char *test = (char*) malloc(12*sizeof(char));
strcpy(test, "testingonly");
printf("string is: %s\n",test);
free(test);
return 0;
}
marchera
Ceci est pour allouer la mémoire:
char *string;
string = (char *) malloc(15);
Ceci est pour sauvegarder les données:
strcpy(str, "kavitajain");
printf("String = %s, Address = %u\n", str, str);