将结构成员指针分配给另一个动态内存分配的指针是否安全?

Jac*_*row 5 c memory struct pointers scope

#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;
}
Run Code Online (Sandbox Code Playgroud)

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

我听说数组变量本来就是局部变量,但在函数结束后会被释放。我想知道这是否适用于分配内存的局部变量。

像这样:

char *test(void) {
    char s[100];
    return s;
}
Run Code Online (Sandbox Code Playgroud)

s将在函数结束时消失,所以我想知道这是否适用于我的结构,特别是我不是返回,而是更改成员。

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

Som*_*ude 5

test_new函数中我们看一下这两行:

// 1
char *s = malloc(100);

// 2
test->str = s;
Run Code Online (Sandbox Code Playgroud)

1你有这样的事情之后:

+---+ +--------------------------------------------+
| s | --> | 由 malloc 分配的内存... |
+---+ +--------------------------------------------+

然后当2你有这样的事情之后:

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

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

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

这完全没问题。


Adr*_*ica 2

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

错误的地方(使用第二个片段中的本地内存示例)将是这样的:

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.
}
Run Code Online (Sandbox Code Playgroud)

上面的错误代码将编译(语法上是正确的),但任何像样的编译器都会(或应该)警告您使用指向局部变量的指针。