Somme de contrôle incorrecte pour objet libéré sur le malloc
- Je obtenir une
malloc: *** error for object 0x1001012f8: incorrect checksum for freed object
- object was probably modified after being freed.
*** set a breakpoint in malloc_error_break to debug
erreur dans la fonction suivante:
char* substr(const char* source, const char* start, const char* end) {
char *path_start, *path_end, *path;
int path_len, needle_len = strlen(start);
path_start = strcasestr(source, start);
if (path_start != NULL) {
path_start += needle_len;
path_end = strcasestr(path_start, end);
path_len = path_end - path_start;
path = malloc(path_len + 1);
strncpy(path, path_start, path_len);
path[path_len] = 'char* substr(const char* source, const char* start, const char* end) {
char *path_start, *path_end, *path;
int path_len, needle_len = strlen(start);
path_start = strcasestr(source, start);
if (path_start != NULL) {
path_start += needle_len;
path_end = strcasestr(path_start, end);
path_len = path_end - path_start;
path = malloc(path_len + 1);
strncpy(path, path_start, path_len);
path[path_len] = '\0';
} else {
path = NULL;
}
return path;
}
';
} else {
path = NULL;
}
return path;
}
Comment puis-je faire ce travail? Quand j'ai réécrire la fonction d'allouer de la mémoire à l'aide de path[path_len + 1]
il fonctionne très bien.
Maintenant, la partie que je ne comprends pas, c'est que je n'ai même jamais appel free
en tout point à ma demande, comme toute mémoire allouée est nécessaire pour le programme jusqu'à ce qu'il existe (ce qui, autant que je sache, entraînera la nullité de toute la mémoire allouée de toute façon?!)
Alors, comment un objet libéré être endommagé si je n'ai jamais libre?
La fonction est appelée dans celui-ci:
char *read_response(int sock) {
int bytes_read;
char *buf = (char*)malloc(BUF_SIZE);
char *cur_position = buf;
while ((bytes_read = read(sock, cur_position, BUF_SIZE)) > 0) {
cur_position += bytes_read;
buf = realloc(buf, sizeof(buf) + BUF_SIZE);
}
int status = atoi(substr(buf, "HTTP/1.0 ", " "));
Il est le realloc
, suis-je à l'aide de ce mal? Je veux lire l'intégralité de la réponse du serveur, j'ai donc réaffecter après chaque itération, n'est-ce pas?
free()
n'importe où dans le code.L'erreur est suggérer que vous foiré le tas par la modification d'une variable après la libération, mais cela ne veut pas dire que c'est la façon dont vous l'avez fait. Ce que vous faites est de gâcher le tas.
Est-ce que votre programme d'appels
realloc
?Alors que ce n'est pas lié à l'erreur, vous êtes encore abuser de
strncpy
. Si vous savez exactement combien de caractères vous avez besoin de copier, utiliser memcpy
ou une sorte de strlcpy
au moins. strncpy
est complètement hors de propos ici, même s'il "fonctionne".Je vois un
realloc()
. Ce qui compte comme un free()
.
OriginalL'auteur Florian Peschka | 2012-07-12
Vous devez vous connecter pour publier un commentaire.
Dans
read_response
, vous êtes probablement en écrasant la fin de la mémoire tampon pointé parbuf
.Le problème est que buf est un pointeur, donc
sizeof(buf)
sera de retour de la taille d'un pointeur (probablement 4 ou 8 en fonction de votre PROCESSEUR). Vous utilisezsizeof
comme sibuf
étaient un tableau, qui n'est pas vraiment la même chose qu'un pointeur en C, bien qu'ils semblent interchangeables dans certains contextes.Au lieu d'utiliser
sizeof
, vous avez besoin de garder la trace de la dernière taille que vous avez alloué pourbuf
, et ajouterBUF_SIZE
à chaque fois que vous agrandir la mémoire tampon.Vous devriez également considérer que le
read
opération renvoie peut-être considérablement moins de caractères queBUF_SIZE
sur chaque appel, donc en faisant unrealloc
surbuf
à chaque itération peut-être exagéré. Qui ne sera probablement pas causer des problèmes pour vous en termes d'exactitude, de bien; il n'utilisera plus de mémoire que nécessaire.Je ferais quelque chose de plus comme le code ci-dessous.
Cette version a l'avantage de ne pas essayer d'allouer plus d'espace si la
read
appel revient avec seulement quelques octets de données.OriginalL'auteur Nate C-K
Cette ligne
est faux. Tous les réaffectations sont de la même taille,
BUF_SIZE + sizeof(char*)
. Ensuite, vous êtes à l'écriture de la mémoire non allouée lors de la lecture de la prise, de l'écrasement de la mémoire précédemmentfree
d par unrealloc
.Vous devez garder une trace de la taille allouée,
strlen(buf) + BUF_SIZE
travail correctement?Et ici est le C-entrée de la FAQ.
BUF_SIZE peut-être besoin d'un
+ 1
pour les 0-terminator, et il ne fonctionnera que si il y a un 0-terminatorbuf
.read
n'ajoute pas automatiquement.Pourriez-vous élaborer votre exemple de plus? Peut-être avec la boucle? Je ne pouvais vraiment utiliser un indicateur en la matière. Comment puis-je ajouter de la terminaison à la fin de la mémoire tampon après l'avoir lu en entier?
Vous pouvez mettre dans le 0-terminator facilement, puisque vous avez
cur_position
pour suivre la fin. Aprèscur_position += bytes_read;
il suffit d'insérer une*cur_position = 0;
, mais assurez-vous qu'il y a de l'espace dans la mémoire tampon. Mais Si vous utilisez Nate C-K de l'exemple, vous n'avez pas besoin de le 0-terminator jusqu'à ce que après la boucle. (Pour toutes les chaînes de caractères les fonctions de gestion, il est généralement requis. Si votre entrée est comme prévu,int status = atoi(substr(buf, "HTTP/1.0 ", " "));
fonctionne même sans le 0-terminator, mais pour mal formée d'entrée qui peuvent tomber en panne mal.)OriginalL'auteur Daniel Fischer