【发布时间】:2018-08-30 15:49:29
【问题描述】:
在编写一些 C 代码时,我遇到了这个奇怪的错误。
我在代码中出错并写信给buf 而不是&buf,但它几乎正常工作。
...
void* buf;
int ret;
int fd = open("1", O_CREAT | O_RDWR, 0777);
write(fd, "test\n", 5);
lseek(fd, 0, SEEK_SET);
ret = read(fd, buf, 5); // Yes, this should be &buf
printf("Ret: %d Str: %s\n", ret, buf);
---- output ----
Ret: 5 Str: test\n
这段代码有效,我在标准输出中得到了test\n,即使我的读取调用中应该有&buf。请,我知道将buf 更改为&buf 有效。那不是问题。
这是行不通的:
...
void* buf;
void* blah = "a"; // Using char* still did not work
int ret;
int fd = open("1", O_CREAT | O_RDWR, 0777);
write(fd, "test\n", 5);
lseek(fd, 0, SEEK_SET);
ret = read(fd, buf, 5);
printf("Ret: %d Str: %s\n", ret, buf);
---- output ----
Ret: -1 Str: 1�I��^H��H���PTI��`@
文件1 的二进制文件对于两个程序是相同的。写信给1没有错误。
为什么第一个代码sn-p有效?
添加一个从未使用过的变量如何使其不再 工作吗?
为什么首先写信给
buf而不是&buf?
这是每个二进制文件中的字符串部分:
功能代码:
0000770: 0100 0200 0000 0000 0000 0000 0000 0000 ................
0000780: 3100 7465 7374 0a00 4572 723a 2025 640a 1.test..Err: %d.
0000790: 0a00 5374 723a 2025 730a 0000 011b 033b ..Str: %s......;
00007a0: 3000 0000 0500 0000 34fd ffff 7c00 0000 0.......4...|...
故障代码:
0000770: 0100 0200 0000 0000 0000 0000 0000 0000 ................
0000780: 6100 3100 7465 7374 0a00 4572 723a 2025 a.1.test..Err: %
0000790: 640a 0a00 5374 723a 2025 730a 0000 0000 d...Str: %s.....
00007a0: 011b 033b 3400 0000 0500 0000 30fd ffff ...;4.......0...
谢谢。
【问题讨论】:
-
除非您没有显示更多代码,否则这些“工作”都不会,因为您的 buf 指针实际上并没有指向任何有意义的东西,这意味着尝试读取它是未定义的并且任何事情都可能发生。你没有收到警告吗?如果您没有使用一组体面的警告进行编译(
-Wall -Wextra用于 gcc 和 clang(并且您还应该添加 Asan (-fsanitize=address))),请这样做,并注意 给他们.. -
不,这不应该是
&buf,除非你试图使该变量指向从文件中读取的地址(你不是,也不应该这样做) -
嗨,肖恩。我删除的唯一代码是
int main() { ... }。我没有从 void 指针中读取。我正在读取文件1并将其放入buf,这就是正在做的事情和我想要做的事情。至于那些警告,不,除了在我的 printf 语句中使用-Wall -Wextra标签设置void*和%s之外,我没有收到任何警告。void* buf也是可识别的读取输入,如here 所示。这就是我遵循的地方。编辑:请注意读取函数的返回值。第一次没有错误。
标签: linux system-calls void dereference