【问题标题】:dynamic allocation and returning a local variable动态分配并返回一个局部变量
【发布时间】:2012-09-09 14:38:08
【问题描述】:

在这段代码中,我试图创建一个列表,其中包含来自输​​入文件的所有字符,我的主要问题是句子“你不能返回函数的局部变量”Iv'e被告知这让我很困惑。我动态分配了一个 List 并返回它,我可以只定义 List list 而不使用动态分配并返回它吗?我相信这是错误的,因为所有信息都会被自动删除,我只剩下我创建的原始列表的地址。

这里是更多信息的代码:

typedef struct Item {
    char tav;
    struct Item* next;
} Item;

typedef struct List {
    Item* head;
} List;

List* create(char* path) {
    FILE* file;
    List* list;
    Item* trav;
    Item* curr;
    char c;

    file=fopen(path, "r");
    if (file==NULL) {
        printf("The file's not found");
        assert(0);
    }

    if (fscanf(file, "%c", &c)!=1) {
        printf("The file is empty");
        assert(0);
    }
    trav=(Item *)calloc(1, sizeof(Item));
    trav->tav=c;
    list=(List *)calloc(1, sizeof(List)); /* allocating dynamiclly the list so it won't be lost at the end of the function*/
    list->head=trav;

    while (fscanf(file, "%c", &c)==1) {
        curr=(Item*)calloc(1, sizeof(Item));
        curr->tav=c;
        trav->next=curr;
        trav=curr;
    }
    trav->next=NULL;

    fclose(file);

    return list;

}

我说的对吗?这是必要的吗?我可以定义 List 而不是一个指向一个返回它的指针吗?

【问题讨论】:

    标签: c variables dynamic


    【解决方案1】:

    您不能返回指向函数局部变量的指针。局部变量不会超出函数的范围({,})。
    返回函数局部变量的地址将为您提供所谓的未定义行为

    你可以很好地返回:

    • 按值或局部变量
    • 指向动态分配内存的指针

    首选第一个,除非您真的因为返回副本而对内存过多感到困扰。

    我可以只定义没有动态分配的 List 列表并返回它吗?

    是的,
    只要你有:

    List create(char* path); 
    

    【讨论】:

    • 感谢您的回答。在我的情况下,返回非动态分配的列表也可以吗?我的意思是如果我的主要功能将其用作“列表列表=创建(文件)”?
    【解决方案2】:

    不能返回函数的局部变量

    这句话完全错误。例如在这个函数中:

    int f(void)
    {
        int x = 5;
        return x;
    }
    

    是一个完全有效的函数,您在其中返回一个局部变量。

    你应该知道的是你不能(或者说不应该)返回函数的局部变量的地址。这是因为函数返回后地址指向垃圾,不再可用。

    在您的示例中,您可以非常安全地定义一个本地 List 并返回它。

    请注意,您仍然需要动态分配trav,即您不能将Item 类型的局部变量和list->head 指向它,原因与上述相同。

    【讨论】:

    • 您正在将副本返回到那里的局部变量。
    • @moooeeeep,我相信这是暗示的。否则,“返回局部变量”是什么意思?
    • 我在这个练习中被告知“创建的列表必须通过函数的参数返回”-这是什么意思?你认为我应该创建“void create(&list, file)”函数吗?
    • @Shahbaz 否则,这只是一个草率的表述,并不清楚它的真实情况。关键是,当函数退出时,实际的局部变量就消失了,但它的 value 可以作为函数的返回值传递。另外,先前本地的地址确实可以在函数范围之外传递,但是当函数结束时您不再被允许使用它(即使旧值可能仍然存在,而不是 garbage )。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-25
    • 1970-01-01
    • 1970-01-01
    • 2021-12-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多