我没有找到这个问题的确切答案,所以这是一个愚蠢的问题,或者只是显而易见的问题。我想知道它是否会产生未定义的行为。
我定义了一些结构类型:
typedef struct {
char string1[17];
char string2[33];
int someInt;
float someFloat;
} my_struct_t;
我需要该结构的多个实例(就像你在struct数组中一样),但是在编译时对象的数量是未知的。
像这样初始化它是否正确?
my_struct_t *myStruct;
size_t noOfElements;
size_t completeSize;
int index;
/* ...code which sets the number of elements at runtime... */
completeSize = sizeof(my_struct_t) * noOfElements;
myStruct = malloc(completeSize);
memset(myStruct, 0, completeSize);
/* ...and then access it as if it were an array...*/
myStruct[index].someInt = 10; // index < noOfElements
这样做是否安全? memset()
部分是我担心的。
答案 0 :(得分:10)
使用malloc
后跟memset
即可,但您可能希望考虑(使用不足)calloc
。例如:
pMyStruct = calloc(noOfElements, sizeof(my_struct_t));
这将为所需数量的元素分配内存,和将它们初始化为二进制零。
答案 1 :(得分:9)
这样做是否安全? memset()部分是我担心的。
是的,它是安全的,因为这不会导致任何未定义的行为(缓冲区溢出,未初始化的值等)。
但是,它不一定会将您的值设置为零。 memset
将位设置为0,但这不一定与设置为一个float
到0
的值(虽然在实践中,它在大多数普通平台上都没问题。)
答案 2 :(得分:4)
这样做是否安全? memset()部分是我担心的。
你担心是对的 - 你的memset
只是将所有位设置为零,这不一定将成员设置为0。
例如,没有什么能保证all-bits-0实际上对于float来说意味着0。对于指针也是如此:使其成为全位-0并不意味着它必然是NULL
。
NULL
可以表示也可以不表示为全位0。引用C FAQ:
空指针的内部(或运行时)表示,可以是 或者可能不是全比特0,并且对于不同的可能是不同的 指针类型。
答案 3 :(得分:1)
代码中的memset
会将所有位设置为0,这可能是也可能不是您想要做的。特别是,不能保证具有全零位的指针是空指针。也不是所有零位的浮点值都为零。
如果您希望代码完全可移植,那么您应该初始化每个元素。
my_struct_t *arr = malloc(N * sizeof arr[0]);
const my_struct_t default_my_struct = { 0 };
for (int i=0; i<N; i++)
arr[i] = default_my_struct;
或者您可以使用C99复合文字进行初始化:
my_struct_t *arr = malloc(N * sizeof arr[0]);
for (int i=0; i<N; i++)
arr[i] = (my_struct_t) { 0 };
在实践中,您必须努力寻找一个C实现,上面的代码与使用memset
的变体的结果不同。