出于教育目的,我正在尝试替换标准流stdout、stdin和stderr。我首先查找了流的数据类型,发现其追溯到具有以下成员(gdb ptype _IO_FILE)的struct _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];
}
然后我尝试复制stdout指针的内存内容:
_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和其他库函数是否只比较标准流的指针?
编辑:我怀疑这是一个实现或平台相关的问题,并且由于所有的意见都表明这是一个问题,我接受了提出问题可能原因的答案。
编辑2:为了缩小问题范围:我正在使用版本为12.04的64位ubuntu和EGLIBC版本为2.15。