2013-03-29 25 views
0

我刚刚创建了下面的代码来帮助调试我们必须编写的基本上最终应该模拟UNIX文件系统的C项目。我一直在试图弄清楚为什么两个看似相同的代码块会产生不同的输出。当我通过在main()文件中键入相同的代码行来模拟与我的函数mkfs()应该具有的行为相同的行为时,它完美地工作,但是当我尝试使用该函数时(实际上是相同的代码行! !!!!!),它只是说RUN RUN FAILED。当我执行当前注释掉的main()函数内部的代码时,它的效果很好,而且确实在控制台打印了“/”,但是当我尝试创建一个指向文件系统的指针时,调用它的mkfs()打印出相同的字符串,但它不起作用。两个表面上看起来相同的代码段有不同的结果(通过结构指针)

我一定是不理解的东西。下面是代码,但如果你喜欢语法高亮,然后这里是一个小链接引擎收录:http://pastebin.com/9yCB1iND

#include <stdio.h> 
#include <stdlib.h> 

typedef struct directory { 
    const char *name; 
    struct file *f; 
    struct directory *dir; 
} Directory; 

typedef struct file { 
    const char *name; 
    struct file *next; 
    struct file *prev; 
    Directory *parent; 
} File; 

typedef struct filesystem { 
    Directory *rt; 
    Directory *cd; 
} Filesystem; 

/* The function mkfs() initializes the Filesystem. It takes a pointer to a 
* filesystem as its single parameter and allocates the memory needed (it 
* allocates the space needed to accomodate the two Directory pointers 
* that a filesystem has). */ 
    void mkfs(Filesystem *files){ 

    /*The first malloc creates enough space for Filesystem itself*/ 
    files = malloc(sizeof(Filesystem)); 

    /*The second malloc creates enough space for a root Directory*/ 
    files->rt = malloc(sizeof(Directory)); 

    /*We make a character array with a single slash that represents root*/ 
    char nv[] = "/"; 
    /* nv is a pointer to the first element in the array nv[]. 
    * We point 'files->rt->name' to the first character in the array nv[]. */ 
    files->rt->name = nv; 
    /* Finally, we set files->cd to point to whatever files->rt pointed too, 
    * which is the current directory "/" */ 
    files->cd = files->rt; 
} 


int main(void) { 
    /* 
    Filesystem *files; 
    files = malloc(sizeof(Filesystem)); 
    files->rt = malloc(sizeof(Directory)); 
    char nv[] = "/"; 
    files->rt->name = nv; 
    files->cd = files->rt; 
    printf("%s", files->cd->name); 

     --------------------------------------------------------------------------- 
     Why does the FOLLOWING code not work when the ABOVE code should be "the same" ? 
     --------------------------------------------------------------------------- 
    */ 

    Filesystem *f; 
    mkfs(f); 
    printf("%s", f->cd->name); 

    return (EXIT_SUCCESS); 
} 

回答

1

mkfs功能:

char nv[] = "/"; 
files->rt->name = nv; 

nv是具有自动存储持续时间,寿命,其中端部的阵列当执行熄灭该功能使得files->rt->name成为悬空指针的范围,其中提领导致未定义的行为。您需要动态分配files->rt->name

另请注意,mkfs函数将指针指向Filesystem,它只是传递给它的指针的副本。对指针本身所做的更改对于调用者不可见,这意味着当您拨打printf("%s", f->cd->name);时,您将取消引用未初始化的指针,这也会导致未定义的行为。如果你想mkfs分配内存,并正确初始化指针,那么你应该通过这个指针的地址:

void mkfs(Filesystem **files) { 
    *files = malloc(sizeof(Filesystem)); 
    (*files)->rt = malloc(sizeof(Directory)); 
    char nv[] = "/"; 
    (*files)->rt->name = malloc(strlen(nv) + 1); 
    strcpy((*files)->rt->name, nv); 
    (*files)->cd = (*files)->rt; 
} 

int main(void) { 
    Filesystem *f = NULL; // <-- it's good to keep your variables initialized 
    mkfs(&f); 
    ... 
} 

而如果你不需要你的功能,使更改存储该指针指向但不指针本身,它看起来是这样的:

void mkfs(Filesystem *files) { 
    files->rt = malloc(sizeof(Directory)); 
    char nv[] = "/"; 
    files->rt->name = malloc(strlen(nv) + 1); 
    strcpy(files->rt->name, nv); 
    (*files)->cd = files->rt; 
} 

int main(void) { 
    Filesystem *f; 
    f = malloc(sizeof(Filesystem)); 
    mkfs(f); 
    ... 
} 
+0

所以,如果我做了NV一个全局变量只是让我可以在最初的名称创建“/”的第一个目录,这应该可以解决悬摆指针问题正确吗?但是,然后动态分配文件 - > rt->名称意味着使用malloc(sizeof(“/”)),对吧?我只是想确保我明白你的意思。谢谢 –

+0

正确的说法,就像为了让链表能够在最初没有指向任何东西的情况下工作一样,您必须将指针传递给指向节点的指针,以便能够直接修改第一个指针指向。然而,我们给出的函数声明声明我们必须简单地使用void mkfs(Filesystem *文件)而不是双指针,但我想我可以做一个帮助函数来解决这个问题。 –

+0

@ HeraldD.Precursor:检查代码我现在的答案。我编辑它:) – LihO

2

当你做出这样的

mkfs(f); 

呼叫f副本传递给mkfs的。 该副本是被改变的一个(也就是的malloc的返回值是用来初始化拷贝,然而,在mainf不会改变。

因此,当你在主做

printf("%s", f->cd->name); 

- 这是不确定的行为,因为你正在访问未初始化的指针

也有在你的程序中的其他问题

nv是本地的。到功能。它的生命只是在函数返回之前。所以这是错误的。

相关问题