関数がしばしば値を返す理由は、呼び出し元の関数にエラー状態を返すためです。メモリ関連の関数では、通常、結果があるべき場所 (NULL を含む) と同じポインターです。あなたの例では、my_memset
関数の戻り値を使用したくないかもしれませんが、通常はコード評価に含めることができるためです (これに適した言葉が思いつきません)。
if(!my_memset((void *)str, 'a', 5))
{
printf("An error occurred in my_memset()\n");
}
またはマクロで、たとえば、コピーしたメモリの末尾へのポインターを返すにはchar
:
#define INIT_MEM_PTR_END(a,x) (my_memset((void *)&(a), (x), sizeof(a)) + sizeof(a))
これはおそらく良い例ではありません (さらにa
が既にポインターである場合の潜在的な問題など)。 .
また、ポインターを逆参照する前にポインターを確認する必要があります。たとえばvoid *b
NULL の場合、セグメンテーション違反が発生します。
void *
関数の意図が特定のデータ型へのポインターを渡すときほど明確ではない可能性があるという事実を除いて、を渡すことに問題はありません。内部でも有効なものにキャストしてください。また、このように、関数を使用して、任意のメモリを特定の 16 進数値 (char を介して) またはすべて 0 に非常に簡単に設定することができます。
この場合b
、コピーしようとしている値と同じ型にキャストする必要があるように思われint
ます。ただし、引数が不明になります。サイズはバイトですか、それともポインタにコピーするlen
回数ですか?c
b
あなたはそのメモリ位置にmain()
a をコピーしているので、あなたを a に変更し、あなたをaにキャストし、長さをバイト単位またはコピーする回数にする方が良いでしょう。曖昧さを避ける。char
c
char
b
char*
len
c
*b
あなたが書いた方法では、指定された回数、またはnull文字に出会うまで、最短/最短c
の回数をコピーします。len
それがあなたの意図なら、それは結構です。
void *my_memset(void *b, char c, int len)
{
char *b_char = (char *)b;
if (b == NULL) return NULL;
while(*b_char && len > 0)
{
*b_char = c;
b_char++;
len--;
}
return b; //as this pointer has not changed
}
int main()
{
char *str;
str = strdup("hello");
if (!my_memset((void *)str, 'a', 5))
{
printf("An error occurred in my_memset()\n");
}
else
{
printf("%s\n", str);
}
}