出于教育目的,我尝试替换标准流 stdout、stdin 和 stderr。我首先查找流的数据类型,我追溯到具有以下成员的 struct _IO_FILE (gdb ptype _IO_FILE):
type = struct _IO_FILE {
int _flags;
char *_IO_read_ptr;
char *_IO_read_end;
char *_IO_read_base;
char *_IO_write_base;
char *_IO_write_ptr;
char *_IO_write_end;
char *_IO_buf_base;
char *_IO_buf_end;
char *_IO_save_base;
char *_IO_backup_base;
char *_IO_save_end;
struct _IO_marker *_markers;
struct _IO_FILE *_chain;
int _fileno;
int _flags2;
__off_t _old_offset;
short unsigned int _cur_column;
signed char _vtable_offset;
char _shortbuf[1];
_IO_lock_t *_lock;
__off64_t _offset;
void *__pad1;
void *__pad2;
void *__pad3;
void *__pad4;
size_t __pad5;
int _mode;
char _unused2[20];
}
然后我尝试复制标准输出指针的内存内容:
_IO_FILE f1 = {._flags = -72540028, ._offset = -1, ._old_offset = -1, ._fileno = 1, ._chain = stdin, ._lock = stdout->_lock, .__pad2 = stdout->__pad2 };
_IO_FILE *f2 = stdout;
_IO_FILE *f3 = malloc(sizeof(_IO_FILE));
memcpy(f3, stdout, sizeof(_IO_FILE));
fprintf(&f1, "f1\n"); // doesn't work
fprintf(f2, "f2\n"); // works
fprintf(f3, "f3\n"); // doesn't work
然而,只有指针赋值不会崩溃。我通过 gdb 比较了内存内容,并且全部共享相同的结构成员内容。
尽管这个问题可能与平台相关:fprintf和其他库函数只是将指针与标准流进行比较吗?
编辑:我怀疑这是一个实现或平台相关的问题,并且由于所有意见都表明确实如此,所以我接受了表明问题的一个可能原因的答案。
edit2:缩小问题范围:我使用的是 64 位 ubuntu,版本为 12.04,EGLIBC 版本为 2.15。