Функции причины часто возвращают значение, чтобы вернуть состояние ошибки вызывающей функции. В функциях, связанных с памятью, это обычно тот же указатель, что и ваш результат (включая 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 *
, кроме факта, что намерение функции может быть не таким ясным, как при передаче указателя на определенный тип данных. Убедитесь, что вы применили его к чему-то действительному, хотя внутри. Кроме того, эта функция может использоваться для установки любой памяти на конкретное шестнадцатеричное значение (через char) или все 0 довольно легко.
Казалось бы, в этом случае b
следует отличать от того же типа, что и значение, которое вы пытаетесь скопировать, int
; однако тогда аргумент len
становится неясным: размер в байтах или количество раз c
следует скопировать в указатель b
?
Поскольку в вашем main()
вы копируете char
в эту ячейку памяти, то это как раз лучше, чтобы изменить свою c
к char
, отдать свой b
к более char*
и сделать len
длину в байтах или количество раз c
должно скопированы в *b
. Избегайте двусмысленности.
Способ, которым вы его написали, он скопирует 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);
}
}
Вы не должен любить пространства, много приятеля .. – Maroun
'' б ++ - это проблема, учитывая 'b' точки к' void', который не имеет известного размера. 'b = c;' - это большая проблема, которая, скорее всего, приведет к краху вашего приложения. – mah
Это должно быть что-то вроде 'void ms (char * dst, size_t len, char val) {for (char * p = dst; p! = Dst + len; ++ p) * p = val; } ' –