c - 尝试实现 bzero 函数会导致分段错误
问题描述
我正在尝试重新编码一个给出分段错误的 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 = '\0';
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);
}
解决了这个问题。感谢所有的帮助。
解决方案
- 他们为索引使用了错误的类型。它应该不是 size_t
unsigned int
。 - 第二个函数应该返回
void *
值,但它不返回任何 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;
}
推荐阅读
- python - 尝试将 RegEX 与“使用 Python 自动化无聊的东西”中的 Excel 练习结合起来
- python - 为什么这个打印不一样?
- java - 如何用 Spring JPA 替换 CriteriaBuilder
- python - 如何使用 ruamel.yaml 往返正确设置 YAML 流样式转储?
- macos - Mac clang 安装似乎覆盖了 GCC 安装
- javascript - 我的函数无法返回我的 Firestore 数据
- python - 如何将 ubuntu 降级到 python 3.6?
- azure - 我们如何配置从基于 yaml 的 azure CI 管道的 Jfrog 工件中提取 npm 包?
- r - R 数据帧的匹配对
- javascript - 我的代码具有很高的复杂性。我怎样才能减少它?