出于教育目的,我正在尝试替换标准流stdout、stdin和stderr。我首先查找流的数据类型,并使用以下成员(gdb ptype _IO_FILE )将其追溯到结构_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和其他库函数是否只是比较指向标准流的指针?
编辑:我怀疑这是一个实现或平台相关的问题,因为所有的意见都表明是这样的,所以我接受了这个问题的一个可能原因的答案。
edit2:缩小问题的范围:我使用的是带有12.04版本的64位ubuntu和2.15的EGLIBC版本。
发布于 2014-01-30 19:57:58
根据来自Corvus的评论,在Linus系统上,锁与流相关联,因此复制文件数据结构会干扰锁语义。
(我建议不要立即接受这个答案,以便给Corvus时间输入答案。)
旧的假设:
我怀疑,在您的C实现中,文件对象的位置被用作其含义的一部分。例如,可能存在它们的数组,并且从指向文件对象的指针中减去指向数组的第一个元素的指针,以找到其在数组中的索引。然后这个索引被用作系统调用中的文件号,比如write。
当您分配新的空间时,它不在这个数组中,并且指针算法给出了错误的结果。
https://stackoverflow.com/questions/21451895
复制相似问题