C tampon de l'allocation de la mémoire
Je suis assez nouveau à C donc excusez mon incompétence. Je veux lire un ensemble de fichier Exécutable dans une mémoire tampon:
#include <stdlib.h>
FILE *file = fopen(argv[1], "rb");
long lSize;
fseek(file, 0, SEEK_END);
lSize = ftell(file);
fseek(file, 0, SEEK_SET);
char *buffer = (char*) malloc(sizeof(char)*lSize);
fread(buffer, 1, lSize, file);
Le fichier 6144 bytes (octets stockés correctement dans lSize), mais la taille de mon tampon est à seulement 4 octets, donc que le MZ signature est stockée dans la mémoire tampon.
Pourquoi ne malloc seulement allouer 4 octets dans ce cas?
Edit:
Probablement le char tampon est terminé par le premier 0 dans la MZ en-tête du fichier PE. Si j'ai mis de la mémoire tampon à une certaine valeur, cependant, l'ensemble du fichier sera stocké. Si j'ai mis le tampon de int (= 4 octets), le tampon ne sera pas licencié, mais sera bien sûr plus (vs char = 1 octet). Je veux juste copier le fichier octet par octet avec des octets nuls.
Edit 2:
Le tampon de cours contient tout ce qu'il faut mais si j'essaie d'écrire dans un nouveau fichier avec fwrite, il n'a écrit que jusqu'à la première \0 (qui est de 4 octets). Je viens de recevoir fwrite mal. Corrigé cela. Désolé, le problème n'était pas assez défini.
Comment savez-vous que c'est l'allocation de seulement 4 octets (il ne faut pas, et je ne vois aucune erreur dans votre code). Comment allez-vous déterminer que seulement 4 octets ont été lus/stockées?
Vous n'avez pas à utiliser sizeof à savoir la taille de char. sizeof(char) est toujours de 1. En C, "char" et "octet" sont synonymes.
sizeof(char) == 1
par définition. Si la mémoire ne contient 4 octets, c'est parce que lSize == 4
.Le code est correct. Est-il possible que vous regardez le contenu de la mémoire tampon dans le débogueur, comme une chaîne nul, et ne voir que 4 octets parce que le cinquième est un octet nul? Essayez d'analyser le contenu de la mémoire tampon dans une fenêtre de la mémoire avant et après l'appel fread.
OriginalL'auteur Laughingman | 2011-10-15
Vous devez vous connecter pour publier un commentaire.
Si
lSize
vraiment n'égale6144
puis votre code sera en effet d'allouer6144
octets et ensuite de lire l'intégralité du contenu du fichier. Si vous croyez que seulement 4 octets sont lus c'est probablement parce que la 5ème octet est égal à zéro. Ainsi, lorsque le tampon est interprété comme un zéro chaîne terminée, il se termine à ce point.Vous pouvez inspecter le reste de votre tampon en regardant
buffer[4]
,buffer[5]
, etc.Comme un de côté, vous n'avez pas besoin de jeter le retour de
malloc
, etsizeof(char) == 1
par définition. La meilleure pratique consiste à écrire lemalloc
comme ceci:Mais cela ne changera pas vos résultats.
Je serais prêt à parier que vous êtes à la recherche à la mémoire tampon d'une chaîne se terminant par null dans le débogueur. À l'aide de printf s'arrête à 0. Si seulement 4 octets ont été allouées que vous auriez probablement seg fault sur le fread. Exécuter une boucle for et un tampon d'impression char par char,
printf("%c\n", buffer[i]);
Je ne comprends pas votre modifier. Votre code existant lit tout le fichier dans un buffer. Il est déjà tous là. Mais vous ne pouvez pas le traiter comme une chaîne se terminant par null.
OriginalL'auteur David Heffernan
Parce que vous avez échoué à
#include <stdlib.h>
(et de la fonte de la valeur de retour demalloc()
).Ne pas oublier de
#include <stdlib.h>
de sorte que le compilateur saitmalloc
renvoie une valeur de typevoid*
(plutôt que de supposer qu'elle renvoie unint
) et prend un argument desize_t
type (plutôt que asuuming c'est unint
)Aussi ne jettent pas la valeur de retour de
malloc
. Une valeur de typevoid*
peut être affecté à un objet de pointeur (de tout type) type. La coulée de la valeur de retour fait le compilateur silencieusement convertirint
(présumé lorsque<stdlib.h>
n'a pas été incluses) pour le type de la distribution. Notez que le compilateur puisse se plaindre sans le cast de vous laisser savoir que vous l'avait oublié de l'inclure.La véritable erreur est de ne pas
malloc
l'allocation d'un montant erroné, (je crois qu'il va allouer la quantité correcte de toute façon). L'erreur réelle est en supposant que la fonction malloc retourne un int lorsqu'il renvoie un void*.int
etvoid*
peut être transmis de manière différente (l'un dans un registre, l'autre sur la pile par exemple) ou qu'ils ont des représentations différentes (en complément à deux pourint
et segmenté adresse pourvoid*
), ou tout autre chose (probablementsizeof (int) != sizeof (void*)
).Assurez-vous de jeter la valeur de retour de malloc est une mauvaise pratique, mais une erreur? Je doute que cela, comme je l'ai fait une centaine de milliers de fois (en cours de C++ de fond, où il n'est pas converti implicitement).
pourquoi casting devrait être un problème?
Je comprends que vous sauter sur cette occasion pour faire un point sur le casting de la suite de
malloc()
, mais si c'est la cause, alors l'erreur est à ne pas inclurestdlib.h
et le casting ne cache qu'un avertissement utile. EDIT: après avoir lu les autres commentaires: voir? Mettre les choses de cette façon confond les gens.Selon les commentaires, la véritable erreur est l'omission d'inclure l'en-tête correcte. Le casting de la valeur de retour est un moyen de rendre le compilateur silencieusement accepter l'erreur.
OriginalL'auteur pmg
comment êtes-vous de vérifier la taille de la mémoire tampon, faites-vous un
sizeof(buffer)
? Dans ce cas, vous êtes seulement en voyant la taille d'unpointer to int
qui est de 4 octets. Vous ne pouvez pas obtenir la taille d'un tampon du pointeur. Vous devez le stocker séparément comme vous l'avez fait (enlSize
).Si
malloc()
n'a pas de retourNULL
alors votre tampon est fine et la taille est correcte.OriginalL'auteur RedX