Problèmes d’écriture de la fonction memset

memset fonction memset et mon code est en dessous, j’ai un problème

 void* memsetFun(void* pointer, int c, int size) { if ( pointer != NULL && size > 0 ) { unsigned char* pChar = pointer; int i = 0; for ( i = 0; i < size; ++i) { unsigned char temp = (unsigned char) c; *pChar++ = temp; // or pChar[i] = temp (they both don't work) } } return pointer; } 

J’ai aussi essayé pChar [i] = la valeur que nous voulons et qui ne fonctionne toujours pas. Cela me donne des numéros de corbeille qui n’ont aucun sens.

Et je l’appelle:

 memsetFun(address, num, size); printf("value at %p is %d\n", address, *((int*) address)); 

Où j’appelle l’adresse (je viens d’entrer l’adresse)

Par exemple, si vous imprimez les caractères (c), cela s’imprime comme un caractère étrange qui ressemble à (pour la valeur 4)

 0 0 0 4 

Votre code me semble bien et plusieurs personnes ici ont commenté que cela fonctionne sur leur système.

Donc, la chose évidente à faire est de le déboguer – c’est une compétence qui vous sera utile à l’avenir 🙂 Vous devriez l’apprendre maintenant .

Que génère le code suivant lorsque vous l’exécutez?

 void* memsetFun(void* pointer, int c, int size) { printf("A %x %d %d\n", pointer, c, size); if ( pointer != NULL && size > 0 ) { printf("B\n"); unsigned char* pChar = pointer; int i = 0; for ( i = 0; i < size; ++i) { printf("C %d (%d)", i, *pChar); unsigned char temp = (unsigned char) c; *pChar++ = temp; // or pChar[i] = temp (they both don't work) printf(" -> (%d)", i, *(pChar-1)); } } printf("D\n"); return pointer; } 

La sortie devrait indiquer clairement les chemins empruntés par le code et quels sont vos parameters (ce qui facilitera grandement le processus de débogage).

Mettre à jour:

Si vous remplissez votre bloc de mémoire avec autre chose que des zéros et utilisez ceci:

 printf("value at %p is %d\n", address, *((int*) address)); 

pour l’imprimer, vous obtiendrez des résultats étranges.

Vous demandez en gros qu’un certain nombre de ces octets soient interprétés comme un entier. Ainsi, par exemple, si vous l’avez rempli avec 0x02 octets et que vous avez un type entier de 4 octets, vous obtiendrez l’entier 0x02020202 (33686018) et non 0x02 comme vous pouvez vous en attendre. Si vous voulez voir quelle est la valeur du premier caractère , utilisez:

 printf("value at %p is %d\n", address, *((char*) address)); 

Et sur la base de votre dernière mise à jour de question:

Par exemple, si vous imprimez les caractères (c), cela s’imprime comme un caractère étrange qui ressemble à (pour la valeur 4)
0 0
0 4

Si c’est un seul personnage et que vous l’imprimez comme un personnage, il n’y a probablement rien de mal. De nombreux stream de sortie vous donneront cela pour un caractère de contrôle (CTRL-D dans ce cas, code ASCII 4). Si vous le remplissiez plutôt avec le code ASCII 0x30 (48), vous verriez le caractère «0» ou ASCII 0x41 (65) vous donnerait un «A».

Comme indiqué précédemment, votre fonction fonctionne comme il se doit. Voici un exemple complet:

 #include  #include  void* memsetFun(void* pointer, int c, int size) { if ( pointer != NULL && size > 0 ) { unsigned char* pChar = pointer; int i = 0; for ( i = 0; i < size; ++i) { unsigned char temp = (unsigned char) c; *pChar++ = temp; // or pChar[i] = temp (they both don't work) } } return pointer; } int main() { // Your memset char a[10]; memsetFun(a, 'A', sizeof(a)); // Uses system memset for verification char b[10]; memset(b, 'A', sizeof(b)); assert(sizeof(a) == sizeof(b)); assert(memcmp(a, b, sizeof(b)) == 0); return 0; } 

return p; empêche cette compilation: p n’est pas défini.

Un problème d’efficacité mineur – en pratique, cela aurait peu d’effet, car tout bon compilateur le réorganiserait, mais les perfectionnistes du codage ne le laisseraient pas restr – l’affectation à temp est dans la boucle, mais c’est la même affectation à chaque fois. C’est-à-dire que l’affectation à temp peut être déplacée avant la boucle.

Vous retournez p , qui n’est pas défini / ne pointe rien en particulier. Peut-être que tu voulais dire pointer ?

Le code est logiquement correct. Avec le changement de pointer p =>, cela fonctionne correctement.

Clarifiez comment exactement cela “ne fonctionne pas”. Peut-être que vous ne comprenez pas ce qu’il est censé faire?

Vous obtenez probablement des numéros de corbeille parce que vous passez d’un entier (4 octets) à un caractère non signé (1 octet). Ainsi, si c> 255 ou <0, vous ne pourrez pas modifier les valeurs que vous vous attendez.

J’ai effectué un test si votre programme définissant la mémoire d’un vecteur int de 5 éléments définissant la valeur 0x01.

Le problème ici est que vous effectuez une itération dans un vecteur de type int par exemple (qui est de 4 octets), mais que vous le parcourez à l’aide de l’arithmétique de pointeur de caractère (1 octet). Si vous voulez memset 0x01 par exemple, vous écrirez ce nombre par valeur dans le vecteur: 00000001000000000000000100000001 qui me donne la même valeur en utilisant le memset original.

Votre fonction, telle quelle , fonctionne pour moi.

Je suppose que vous l’appelez mal. Je l’appelle comme ça

 char a[100]; memsetFun(a, 0, sizeof a); int b[100]; memsetFun(b, 0, sizeof b); 

Comment appelez-vous votre memsetFun() ?

modifier

Avec

 int b[100]; memsetFun(b, 9, sizeof b); 

comme un int est composé de 4 octets (sur mon système), chaque valeur sera définie sur 0x09090909 ou 151587081

C’est exactement ce que c’est censé faire. Votre fonction fonctionne parfaitement bien. La valeur “0x4” n’est pas le caractère ASCII “4”.