关于在Hangman项目中使用unistd.h的read()函数读取单字节时是否需要NULL终止缓冲区的技术问询
关于Hangman项目中单个字符缓冲区是否需要NULL终止的问题
首先得指出你代码里的一个关键错误——read(fd, &buf, 1)这里的参数传错了!buf已经是你malloc出来的内存的指针了,你应该直接传buf,而不是&buf(后者是指针变量本身的地址),现在这么写会把输入数据写到指针变量的内存位置,大概率会导致内存错误,赶紧改成read(fd, buf, 1)。
回到你的核心问题:是否需要给单个字符的缓冲区加NULL终止?分两种情况看:
- 如果之后要把这个缓冲区当作C字符串使用:比如用
printf("%s", buf)打印、用strlen计算长度、或者和其他字符串做拼接/比较,那必须要加NULL终止。C标准库的所有字符串处理函数都是依赖末尾的\0来识别字符串结束位置的,没有的话会触发未定义行为——函数会一直读取内存直到碰到一个\0,大概率会读到垃圾数据,甚至导致程序崩溃。 - 如果只把它当作单个字符处理:比如你只需要取
buf[0]来判断是不是合法的字母,完全不碰任何字符串处理函数,那从功能上来说,NULL终止不是必须的。但从代码健壮性和可维护性角度,我强烈建议加上:一来这只需要多写一个字节的内存(几乎没成本),二来万一之后你修改代码,需要把这个输入当作字符串处理(比如记录用户的输入历史),就不会突然出现奇怪的bug。
另外补充一下你的函数的小问题:read的返回值可能是0(表示读到EOF)或者-1(表示读取错误),你现在的逻辑是只要返回值非0就认为成功,但其实只有返回值等于1的时候才是真的读到了一个字符。同时读取失败时要释放malloc的内存,避免内存泄漏,调整后的代码可以参考:
char *read_one_byte(int fd) { char *buf; ssize_t read_bytes; // 注意用ssize_t匹配read的返回类型 if (!(buf = malloc(sizeof(char) * 2))) return NULL; read_bytes = read(fd, buf, 1); if (read_bytes == 1) { buf[1] = '\0'; return buf; } else { free(buf); // 读取失败时释放已分配的内存 return NULL; } }
内容的提问来源于stack exchange,提问作者Durian Sosa
相关产品推荐
相关产品推荐

