Когда я запускаю приведенную ниже программу, я не понимаю, почему buf.data
пуст. Сначала я подумал, что это может быть мое непонимание памяти, поэтому я попытался высвободить буферный массив, но это не изменилось, выводят программы.
#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 {
FILE *f;
};
void StandardOut_write(struct StandardOut *w, char c) { fputc(c, w->f); }
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){stdout},
.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, поэтому не знаю, является ли этот код хорошей или плохой практикой. Просто бездельничаю.
Вот более упрощенный пример, описывающий ту же проблему.
#include <stddef.h>
#include <stdio.h>
struct Buffer {
char *data;
size_t size;
size_t offset;
};
void buf_write(struct Buffer *b, const char c) {
if (b->size > 0) {
*b->data++ = c;
b->size--;
}
}
void buf_print(struct Buffer *b, const char *s) {
while (*s)
buf_write(b, *s++);
}
int main() {
char data[32];
struct Buffer buf = {data, 32};
buf_print(&buf, "Hello, world!\n");
printf("buf.data = %s\n", buf.data);
printf("data = %s\n", data);
}
Почему в выводе программы не отображается buf.data?
# program output
buf.data =
data = Hello, world!
Buffer_write
прибавки b->data
. Для b
передается адрес bufw.impl
. Таким образом, bufw.impl.data
увеличивается и больше не указывает на начало массива data
. Позже buf
становится копией bufw.impl
. Итак, когда fprint(&stdoutw, buf.data);
выполняется, buf.data
указывает после строки, которая была скопирована в data
. Память там неинициализирована.