Разыменование указателя на тип void в С

Я написал простенькую программу воспроизводящую поведение библиотечной функции memchr (The memchr() function scans the initial n bytes of the memory area pointed to by s for the first instance of c.) При компиляции компилятор жалуется на эту строчку <return ((unsigned char*)(s[i]));> что я пытаюсь разыменовать указатель на void. Но я не понимаю почему - ведь я уже привел тип void к типу unsigned char*... Если я пишу так: <return ((unsigned char*)(s + i));> то все работает. Объяните пожалуйста почему?


void    *ft_memchr(const void *s, int c, size_t n)
{
    size_t i;
    i = 0;
    while (i < n)
    {
        if (((unsigned char*)s)[i] == (unsigned char)c)
            return ((unsigned char*)(s[i]));
        i++;
    }
    return (0);
}

#include <stdio.h>
int main()
{
    char str[] = {'a', 'b', 'c', 'd', 'e'};

    char* ptr = ft_memchr(str, 'c', 4);
    if (ptr == NULL)
    {
        printf("none");
    }
    else 
    {
        printf("%c\n", ptr[0]);
    }
return 0;
}

Ответы (2 шт):

Автор решения: Harry

Ай-я-яй! Ваша функция возвращает void*, не const void*, а это нехорошо... Z-то вы указатель на const!

Словом, как-то так - при вольностях С с типами - вполне работает:

const void *ft_memchr(const void *ss, int c, size_t n)
{
    const unsigned char * s = ss;
    for(size_t i = 0; i<n; ++i)
        if (s[i] == (unsigned char)c) return s+i;
    return NULL;
}
→ Ссылка
Автор решения: AlexGlebe
return ((unsigned char*)(s[i]));

индексация [ i ] : void * типа не будет работать, так как размер типа неизвестен.

Сначала нужно привести тип указателя на тип известного размера.

А так как вам нужно возвращать указатель, то можно так :

return (unsigned char*)s + i ;

или

return & ((unsigned char*)s)[i] ;

И не забывать, что у вас аргумент константный, и нужно вернуть указатель тоже константный.

void const   *ft_memchr(const void *s, int c, size_t n)
..
char const * ptr = ft_memchr(str, 'c', 4);
→ Ссылка