以这种方式使用复合文字安全地初始化指针,这有可能吗?
#include <stdio.h>
#include <string.h>
void numbers(int **p)
{
*p = (int []){1, 2, 3};
}
void chars(char **p)
{
*p = (char[]){'a','b','c'};
}
int main()
{
int *n;
char *ch;
numbers(&n);
chars(&ch);
printf("%d %c %c\n", n[0], ch[0], ch[1]);
}
输出:
1 a b
我不完全了解它的工作方式,这与带有局部变量的init指针不同吗?
如果我尝试打印:
printf("%s\n", ch);
什么也没打印。
答案 0 :(得分:5)
在函数内部声明的复合文字具有与其封闭块相关的自动存储持续时间(C 2018 6.5.2.5 5),这意味着其寿命在该块执行结束时结束。
在numbers
内,*p = (int []){1, 2, 3};
将复合文字的地址分配给*p
。当numbers
返回时,复合文字立即不存在,并且指针无效。此后,使用指针的程序的行为是不确定的。该程序可能能够打印值,因为数据仍在内存中,或者该程序可能会打印不同的值,因为内存已更改,或者该程序可能因为尝试访问不可访问的内存而被捕获,或者程序的整个行为可能会更改之所以如此激烈,是因为编译器优化将未定义的行为完全改变了。
答案 1 :(得分:3)
这取决于复合文字的放置位置。
C17 6.5.2.5§5
复合文字的值是由初始化的未命名对象的值。 初始化列表。如果复合文字出现在函数主体之外,则对象 具有静态存储期限;否则,它具有与 封闭块。
也就是说,如果复合文字位于局部范围内,则其工作原理与局部变量/数组完全相同,并且从函数返回指向它的指针 不是安全的。
但是,如果在文件作用域中声明它,则它的作用与具有静态存储持续时间的任何其他变量一样,您可以安全地返回指向它的指针。但是,这样做可能表明设计存在问题。另外,您还将在多线程应用程序中遇到常见的线程安全问题。