当我运行下面的程序时,我不明白为什么buf.data
是空的。起初我以为可能是我对内存的误解,所以我尝试 malloc 缓冲区数组,但它没有改变,程序输出。
#include <stdio.h>
typedef void Write(void *, char);
struct Writer {
void *impl;
Write *write;
};
void fprint(struct Writer *w, const char *s) {
while (*s)
w->write(w->impl, *s++);
}
struct StandardOut {};
void StandardOut_write(struct StandardOut *w, char c) { fputc(c, stdout); }
struct Buffer {
char *data;
size_t size;
};
void Buffer_write(struct Buffer *b, char c) {
if (b->size > 0) {
*b->data++ = c;
b->size--;
}
}
int main() {
struct Writer stdoutw = (struct Writer){
.impl = &(struct StandardOut){},
.write = (Write *)StandardOut_write,
};
fprint(&stdoutw, "console meat\n");
char data[1024];
struct Writer bufw = (struct Writer){
.impl = &(struct Buffer){.data = data, .size = sizeof(data)},
.write = (Write *)Buffer_write,
};
fprint(&bufw, "buffered beefalo\n");
struct Buffer buf = *(struct Buffer *)bufw.impl;
fprint(&stdoutw, buf.data);
fprint(&stdoutw, data[0] ? data : "buffer is empty");
}
这是该程序的输出:
❯ zig cc interfaces.c
❯ ./a.out
console meat
buffered beefalo
mains
因此它不会打印缓冲区中的消息。此外,从角度来看,数组不为空。因为否则ternary
应该打印消息,而我们根本看不到缓冲的消息。
我不懂任何 C 语言,所以我不知道这段代码是好还是坏。只是瞎搞而已。
Buffer_write
递增b->data
。对于b
,它传递了 的地址bufw.impl
。因此bufw.impl.data
递增并且不再指向数组的开头data
。buf
稍后设置为 的副本bufw.impl
。因此,当fprint(&stdoutw, buf.data);
执行时,buf.data
指向复制到 中的字符串之后data
。那里的内存未初始化。