【问题标题】:Is it safe to assign a struct member pointer to another dynamically memory allocated pointer?将结构成员指针分配给另一个动态内存分配的指针是否安全?
【发布时间】:2021-02-14 10:48:00
【问题描述】:
#include <stdio.h>
#include <stdlib.h>

struct Test {
    const char *str;
};

void test_new(Test *test) {
    char *s = malloc(100);
    
    s[0] = 'H';
    s[1] = 'i';
    s[2] = '\0';
    
    test->str = s;
}

int main(void) {
    struct Test test;
    
    test_new(&test);
    
    puts(test.str);
    free(test.str);
    
    return 0;
}

这是允许的吗?将结构成员分配给test_new 函数中的局部变量(字符指针)? (test-&gt;str = s 是否允许?)

我听说数组变量,当它是本地的时候,在函数结束后被释放。我想知道这是否适用于内存分配的局部变量。

像这样:

char *test(void) {
    char s[100];
    return s;
}

s 将在函数结束时消失,所以我想知道这是否适用于我的结构,尤其是我没有返回,而是更改了一个成员。

将结构成员指针(test-&gt;str)分配给另一个动态内存分配的指针(s)是否安全?

【问题讨论】:

    标签: c pointers memory struct scope


    【解决方案1】:

    test_new 函数看一下这两行:

    // 1
    char *s = malloc(100);
    
    // 2
    test->str = s;
    

    1 之后你有这样的东西:

    +---+ +------------------+ |小号 | --> | malloc 分配的内存... | +---+ +------------------+

    那么在2 之后你会得到这样的东西:

    +---+ |小号 | ----------\ +---+ \ +-------------------+ >--> | malloc 分配的内存... | +-----------+ / +-------------------+ |测试->str | --/ +-----------+

    然后一旦test_new 返回,main 函数中就只有这个了:

    +----------+ +-------------------+ |测试.str | --> | malloc 分配的内存... | +----------+ +-------------------+

    这很好。

    【讨论】:

    • 感谢您创建图片以查看发生了什么。我以不同的方式想到了 malloc,但是在看了这个之后,我现在可以清楚地看到发生了什么。我非常感谢您仅通过文本表示内存分配的方式。
    【解决方案2】:

    test_new 函数中完成的分配/分配是允许的并且是安全的。这是因为char *s = malloc(100); 行在堆上分配内存(而不是在“本地”堆栈上),而test-&gt;str = s; 行将指向分配内存的指针分配给通过引用传递的结构的成员。因此,调用代码的结构变量中的该成员将按照您的意愿进行修改。

    会有什么问题(在你的第二个 sn-p 中使用本地内存的例子)会是这样的:

    void test_bad(Test *test) {
        char s[100]; // Local memory - gone when function returns
        s[0] = 'H';
        s[1] = 'i';
        s[2] = '\0';    
        test->str = s; // Pointer member of structure will be invalid after the return.
    }
    

    上面的 bad 代码会编译(它是语法正确的),但任何体面的编译器都会(或应该)警告你使用指向局部变量的指针。

    【讨论】:

    • 在您发布的代码中,即使我可能永远不会创建静态变量,但创建static char s[100]; 是安全的,对吧?
    • @JackMurrow 你可以在那里使用static 变量,那将是“安全的”。但是,如果您使用指向许多 不同 结构的指针调用该函数,则每个结构的指针成员将指向 same char 数据。
    猜你喜欢
    • 1970-01-01
    • 2020-03-09
    • 2018-05-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-18
    • 1970-01-01
    相关资源
    最近更新 更多