7

我没有找到这个问题的确切答案,所以要么这是一个愚蠢的问题,要么是显而易见的。我想知道它是否会产生未定义的行为。

我定义了一些结构类型:

typedef struct {
    char string1[17];
    char string2[33];
    int   someInt;
    float someFloat;
} my_struct_t;

我需要该结构的多个实例(就像你在结构数组中一样),但对象的数量在编译时是未知的。

像这样初始化它是否正确?

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()部分是我担心的。

4

4 回答 4

10

就目前而言,使用malloc后跟memset是可以的,但您可能希望考虑使用 (under-used) calloc。例如:

pMyStruct = calloc(noOfElements, sizeof(my_struct_t));

这将为所需数量的元素分配内存,并将它们初始化为二进制零。

于 2012-12-31T12:43:38.407 回答
9

这样做安全吗?memset() 部分是我担心的。

是的,这是安全的,因为这不会导致任何未定义的行为(缓冲区溢出、未初始化的值等)。

但是,它不一定会将您的值设置为零。 memset设置为 0,但这不一定与将 a 设置float为值相同0(尽管在实践中,在大多数普通平台上都可以)。

于 2012-12-31T12:38:39.930 回答
4

这样做安全吗?memset() 部分是我担心的。

你担心是对的 - 你memset只是将所有位设置为零,这并不一定将成员设置为 0。

例如,没有任何东西可以保证 all-bits-0 实际上对于浮点数表示 0。指针也是如此:使其全位为 0 并不意味着它一定是NULL.


编辑

NULL可能会也可能不会被表示为 all-bits-0。引用 C 常见问题解答:

空指针的内部(或运行时)表示,它可能是也可能不是全位 0,并且对于不同的指针类型可能不同。

于 2012-12-31T12:38:52.057 回答
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.

于 2012-12-31T12:53:41.147 回答