C语言 数组定义中的复合文字

qzwqbdag  于 2023-05-28  发布在  其他
关注(0)|答案(3)|浏览(86)

考虑这个数组:

unsigned char* array[] = { (unsigned char[5]){}, (unsigned char[5]){} };

array[0]array[1]是否仍然指向一个有效的内存,即使在array的完整定义之后?这意味着,之后我可以执行例如memcpy(array + 1, "\x01\x02\x03\x04\x05", 5);

9bfwbjaz

9bfwbjaz1#

如果该声明出现在任何函数之外,则array和复合文字具有静态存储期限,因此它们在程序执行期间存在,并且您可以在程序中的任何点使用它们。
如果声明出现在函数内部,则array和复合文字具有与封闭块相关联的自动存储持续时间。只要定义了使用array,就定义了使用复合文字的内存。
注意{}不是严格一致的初始化器;你应该至少给予一个值,如{0}。(GCC和其他编译器可能接受{}

nbnkbykc

nbnkbykc2#

array[0]array[1]是否仍然指向一个有效的内存,即使在array的完整定义之后?
是的。复合文字的生存期,如果不是在文件作用域中声明的,就是它的封闭作用域的生存期。下面的代码:

unsigned char* array[] = { (unsigned char[5]){}, (unsigned char[5]){} };
memcpy(array + 1, "\x01\x02\x03\x04\x05", 5);

将是有效的,但是在严格符合的代码中不允许空的初始值设定项列表,尽管许多编译器支持它作为扩展。一个完全兼容的例子是:

unsigned char* array[] = { (unsigned char[5]){0}, (unsigned char[5]){0} };
memcpy(array + 1, "\x01\x02\x03\x04\x05", 5);
4jb9z9bj

4jb9z9bj3#

是的,只要array有效,array[0]array[1]就有效。
引用标准对复合文字的描述:
复合文字的值是由初始化器列表初始化的未命名对象的值。如果复合文字出现在函数体之外,则对象具有静态存储期限;否则,它具有与包围块相关联的自动存储持续时间。
您有两个unsigned char[5]类型的未命名数组对象,每个对象的初始元素的地址用于初始化array的元素。
如果定义在文件范围内(在任何函数体之外),则未命名的数组对象具有静态存储期限,这意味着它们在程序的整个执行期间存在。
如果定义在函数体内部,在块作用域,那么匿名数组对象的生命周期在执行到达封闭块的末尾时结束--这与array对象的生命周期相同。
请注意,初始化器的{}不构成“块”。
(C23将允许对由复合文字创建的对象的生存期进行更多的控制。它还将使{}成为有效的初始化器;在当前的C语言中,尽管一些编译器允许它作为扩展,但它不被语言所允许。

相关问题