考虑这个数组:
unsigned char* array[] = { (unsigned char[5]){}, (unsigned char[5]){} };
array[0]和array[1]是否仍然指向一个有效的内存,即使在array的完整定义之后?这意味着,之后我可以执行例如memcpy(array + 1, "\x01\x02\x03\x04\x05", 5);
array[0]
array[1]
array
memcpy(array + 1, "\x01\x02\x03\x04\x05", 5);
9bfwbjaz1#
如果该声明出现在任何函数之外,则array和复合文字具有静态存储期限,因此它们在程序执行期间存在,并且您可以在程序中的任何点使用它们。如果声明出现在函数内部,则array和复合文字具有与封闭块相关联的自动存储持续时间。只要定义了使用array,就定义了使用复合文字的内存。注意{}不是严格一致的初始化器;你应该至少给予一个值,如{0}。(GCC和其他编译器可能接受{}。
{}
{0}
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);
4jb9z9bj3#
是的,只要array有效,array[0]和array[1]就有效。引用标准对复合文字的描述:复合文字的值是由初始化器列表初始化的未命名对象的值。如果复合文字出现在函数体之外,则对象具有静态存储期限;否则,它具有与包围块相关联的自动存储持续时间。您有两个unsigned char[5]类型的未命名数组对象,每个对象的初始元素的地址用于初始化array的元素。如果定义在文件范围内(在任何函数体之外),则未命名的数组对象具有静态存储期限,这意味着它们在程序的整个执行期间存在。如果定义在函数体内部,在块作用域,那么匿名数组对象的生命周期在执行到达封闭块的末尾时结束--这与array对象的生命周期相同。请注意,初始化器的{和}不构成“块”。(C23将允许对由复合文字创建的对象的生存期进行更多的控制。它还将使{}成为有效的初始化器;在当前的C语言中,尽管一些编译器允许它作为扩展,但它不被语言所允许。
unsigned char[5]
{
}
3条答案
按热度按时间9bfwbjaz1#
如果该声明出现在任何函数之外,则
array
和复合文字具有静态存储期限,因此它们在程序执行期间存在,并且您可以在程序中的任何点使用它们。如果声明出现在函数内部,则
array
和复合文字具有与封闭块相关联的自动存储持续时间。只要定义了使用array
,就定义了使用复合文字的内存。注意
{}
不是严格一致的初始化器;你应该至少给予一个值,如{0}
。(GCC和其他编译器可能接受{}
。nbnkbykc2#
array[0]
和array[1]
是否仍然指向一个有效的内存,即使在array
的完整定义之后?是的。复合文字的生存期,如果不是在文件作用域中声明的,就是它的封闭作用域的生存期。下面的代码:
将是有效的,但是在严格符合的代码中不允许空的初始值设定项列表,尽管许多编译器支持它作为扩展。一个完全兼容的例子是:
4jb9z9bj3#
是的,只要
array
有效,array[0]
和array[1]
就有效。引用标准对复合文字的描述:
复合文字的值是由初始化器列表初始化的未命名对象的值。如果复合文字出现在函数体之外,则对象具有静态存储期限;否则,它具有与包围块相关联的自动存储持续时间。
您有两个
unsigned char[5]
类型的未命名数组对象,每个对象的初始元素的地址用于初始化array
的元素。如果定义在文件范围内(在任何函数体之外),则未命名的数组对象具有静态存储期限,这意味着它们在程序的整个执行期间存在。
如果定义在函数体内部,在块作用域,那么匿名数组对象的生命周期在执行到达封闭块的末尾时结束--这与
array
对象的生命周期相同。请注意,初始化器的
{
和}
不构成“块”。(C23将允许对由复合文字创建的对象的生存期进行更多的控制。它还将使
{}
成为有效的初始化器;在当前的C语言中,尽管一些编译器允许它作为扩展,但它不被语言所允许。