尝试实现 bzero 函数会出现分段错误

Trying to implement a bzero function gives segmentation fault

我正在尝试重新编码一个会出现分段错误的 bzero 函数,问题是我只是使用相同的方法实现了一个像这样的函数(memset)并且效果很好,但我看不出有什么不同两者之间。 这是代码:

#include <stdlib.h>
    
    void    ft_bzero(void   *b, size_t len)
    {
        size_t i;
        unsigned char *mem;
        unsigned char s;
    
        mem = b;
        s = '[=10=]';
        i = 0;
        while (i < len)
        {
            mem[i] = s;
            i++;
        }
    }
    
    #include <stdio.h>
    int main(void)
    {
        char *b = "bzero";
        
        ft_bzero(b, 4);
        return (0);
    }

这是工作正常的 memset 实现:

#include <stdlib.h>
    
    void    *ft_memset(void *dest,  int c, size_t len)
    {
        size_t  i;
        unsigned char   s;
        unsigned char   *mem;
    
        mem = dest;
        s = c;
        i = 0;
        while (i < len)
        {
            mem[i] = s;
            i++;
        }
        return (dest);
    }
    
    #include <stdio.h>
    #include <string.h>
      
    int main()
    {
        char str[50] = "testing the c ft_memset";
        printf("\nBefore memset(): %s\n", str);
      
        ft_memset(str + 13, '.', 8*sizeof(char));
      
        printf("After memset():  %s", str);
        return (0);
    }

尝试了一段时间后发现我的测试是错误的,更改:

int main(void)
        {
            char *b = "bzero";
            
            ft_bzero(b, 4);
            return (0);
        }

int main(void)
{
    char b[5] = "bzero";
    
    ft_bzero(b, 4);
    return (0);
}

问题已解决。 感谢大家的帮助。

  1. 他们使用了错误的索引类型。应该是 size_t 而不是 unsigned int.
  2. 第二个函数应该 return void * 值,但它不会 return 任何 UB。

我会这样实现(字节版):

void *ft_memset(void *dest,  int c, size_t len)
{
    unsigned char *mem = dest;

    if(mem)
        while (len--)
            *mem++ = c;
    return dest;
}

或更复杂的版本:

#define UNSIGNEDSIZE 4

static_assert(sizeof(unsigned) == UNSIGNEDSIZE, "This function assumes 32 bit unsigned");

#define TAS(v,s) (((unsigned)((v) & 0xff)) << (s))

void *ft_memset(void *dest,  int c, size_t len)
{
    unsigned char *mem = dest;
    unsigned *umem;
    unsigned uval = TAS(c,24) | TAS (c, 16) | TAS(c, 8) | TAS(c,0);
    unsigned trim = sizeof(unsigned) - ((uintptr_t)mem & (sizeof(unsigned) - 1));

    if(mem)
    {
        len -= trim;
        while (trim--)
            *mem++ = c;
        umem = (void *)mem;
        while(len > 3)
        {
            *umem++ = uval;
            len -= sizeof(unsigned);
        }
        mem = (void *)umem;
        while (len--)
            *mem++ = c;
    }   
    return dest;
}