c - 为什么指针会无缘无故地改变?

标签 c os161

我正在做 ops-class 的作业 2 。

以下函数为正在创建的进程引导文件处理程序数组(例如,提供的测试程序的用户进程 here )。

int _fh_bootstrap(struct fharray *fhs){

/* Initialize the file handle array of this process */
fharray_init(fhs);

/* String variables initialized for passage to vfs_open */
char* console_inp = kstrdup(CONSOLE); // CONSOLE = "con:"
char* console_out = kstrdup(console_inp);
char* console_err = kstrdup(console_inp);

/* Return variable */
int ret = 0;

/* Initialize the console files STDIN, STDOUT and STDERR */
struct vnode *stdin;
ret = vfs_open(console_inp,O_RDONLY,0,&stdin);
if(ret != 0){
    return ret;
}
kfree(console_inp);

struct fh *stdinfh = kmalloc(sizeof(struct fh));
ret =  _fh_create(O_RDONLY,stdin,stdinfh);
if(ret != 0){
    return ret;
}

stdinfh->fd = STDIN_FILENO;
fharray_add(fhs,stdinfh,NULL);

struct vnode *stdout;
ret = vfs_open(console_out,O_WRONLY,0,&stdout);
if(ret != 0){
    return ret;
}
kfree(console_out);

struct fh *stdoutfh = kmalloc(sizeof(struct fh));
ret =  _fh_create(O_WRONLY,stdout,stdoutfh);
if(ret != 0){
    return ret;
}

stdoutfh->fd = STDOUT_FILENO;
fharray_add(fhs,stdoutfh,NULL);

struct vnode *stderr;
ret = vfs_open(console_err,O_WRONLY,0,&stderr);
if(ret != 0){
    return ret;
}
kfree(console_err);

struct fh *stderrfh = kmalloc(sizeof(struct fh));
ret =  _fh_create(O_WRONLY,stderr,stderrfh);
if(ret != 0){
    return ret;
}

stderrfh->fd = STDERR_FILENO;
fharray_add(fhs,stderrfh,NULL);

fharray_setsize(fhs,MAX_FD);    

return 0;

/* Initialization of stdin, out and err filehandlers complete */
}

如果我使用 os161-gdb 来单步执行此函数,我会注意到以下内容:

//*stdinfh after the call to _fh_create 
{fd = 0, flag = 0, fh_seek = 0, fh_vnode = 0x80044ddc}

//**stdinfh->fh_vnode
{vn_refcount = 2, vn_countlock = {splk_lock = 0, splk_holder = 0x0}, vn_fs = 0x0,
vn_data = 0x8004ab60, vn_ops = 0x8003e690 <dev_vnode_ops>}

这是奇怪的部分。在单步执行第二次调用 kmalloc(初始化 stdoutfh)后,stdinfh->fh_vnode 指针更改值!

//**stdinfh->fh_vnode
(struct vnode *) 0x1

更奇怪的是,在继续执行以下行后

fharray_add(fhs,stdoutfh,NULL);

*stdoutfh->fh_vnode 和 *stdinfh->fh_vnode 的值相同

1个可能的解释:操作系统是否没有足够的堆内存。我发现这不太可能,即使在假设之后,我也无法准确解释这里发生的事情。

一些额外的代码

  1. _fh_创建
  2. struct fh 定义

    static int _fh_create(int flag, struct vnode *file, struct fh *handle){
    
    KASSERT(file != NULL);
    
    /* W , R , RW */
    if ( 
        ((flag & O_RDONLY) && (flag & O_WRONLY)) ||
        ((flag & O_RDWR) && ((flag & O_RDONLY) || (flag & O_WRONLY)))
    ) {
        handle = NULL;
        return 1;
    }
    
    handle->flag = flag;
    handle->fh_seek = 0;
    handle->fh_vnode = &file;
    
    return 0;
    }
    

    结构 fh { uint32_t fd;//文件描述符 int 标志;//文件处理模式 off_t fh_seek;//寻找文件中的位置 结构 vnode **fh_vnode;//文件的文件对象 }

struct vnode的定义可以在 here 找到.

如果您需要更多信息,请告诉我,感谢您的帮助!

最佳答案

代码handle->fh_vnode正在设置一个指向自动变量(“在堆栈上”)的指针,函数参数是自动变量。函数返回后,这将是一个悬空指针。

要解决此问题,您需要稍微重新设计代码,例如也许struct fh应该只存储file而不是指向file的指针。

关于c - 为什么指针会无缘无故地改变?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41560685/

相关文章:

c - 在此信号处理程序中会发生什么?

c - 参数大小未知的 execl 与 execv

linux - 生成文件错误 - "***missing separator"& "***recipe commences before first target"

linux - 尝试在 Mandriva 上构建 OS161 时出现 "bmake: no system rules (sys.mk)"

c - 我怎样才能知道某个数字是什么时候输入的? C

c - 如何返回指向结构数组内元素的指针?

operating-system - 页码和偏移

operating-system - 为什么每个进程一个页表

c - 'global' 和 'static global' 之间的区别