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

Posted

技术标签:

【中文标题】将结构成员指针分配给另一个动态内存分配的指针是不是安全?【英文标题】: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)是否安全?

【问题讨论】:

【参考方案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 数据。

以上是关于将结构成员指针分配给另一个动态内存分配的指针是不是安全?的主要内容,如果未能解决你的问题,请参考以下文章

如何将结构中的 void 指针分配给另一个结构?

结构体变量 和 结构体指针

C 语言结构体 ( 结构体中嵌套一级指针 | 分配内存时先 为结构体分配内存 然后再为指针分配内存 | 释放内存时先释放 指针成员内存 然后再释放结构头内存 )

C 语言结构体 ( 结构体中嵌套二级指针 | 为 结构体内的二级指针成员 分配内存 | 释放 结构体内的二级指针成员 内存 )

在C中为结构指针数组成员分配地址

为啥没有给另一个进程访问内存位置的权限?