Avoiding memset for a multi-type structure

孤街醉人 提交于 2020-01-17 16:26:27

问题


I would like to avoid using memset() on a structure like this:

typedef struct {
    int size;
    float param1;
} StructA;

typedef struct {
    StructA a;
    unsigned int state;
    float param2;
} Object;

Can I do something like this (pseudo code, I can't check right now)?

Object obj;
int *adr = (int*)&obj;
for (int i; i < sizeof(obj); i++) {
    *adr++ = 0;
}

Will it set every member of obj to zero?

EDIT: to answer questions on comments. I have been working on some cases (with uni-type structures), where memset is twice as slow than initializing by hand. So I will consider trying initializing multi-type structure as well.

Avoiding memcpy() would be nice too (avoiding the <string.h> lib).


回答1:


The universal zero initializer initializes everything (recursively) to zero of the proper type.

Object object = {0};



回答2:


You can create a "zero" object, then copy it to other objects of the same type. Maybe it's faster than memset(), I haven't tested efficiency.

const Object zeroobject = {0};

/* ... */
Object obj;
memcpy(&obj, &zeroobject, sizeof obj);
/* assignment may work too */
obj = zeroobject;



回答3:


memset initializes the structure to all bits zero. This would initialize the integers and the floats to 0 on IEEE compliant architectures but the C Standard does not guarantee it. On an exotic system, this might not initialize param1 or param2 to 0.0.

If the hand coded initialization is faster, use that, or use a static initializer:

Object obj = { 0 };



回答4:


No.

I would prefer to use memset:

memset(&obj, 0, sizeof(obj));

Or if you want it to do your way:

char* adr = (char*)&obj;
for(int i = 0; i < sizeof(obj); i++)
{
    *adr++ = 0;
}



回答5:


You should be using memset, unless it's very hard to do. Like it doesn't exist in your environment and you can't add an equivalent. It's fast, checks all the right edge cases and is essentially bug-free.


That is close enough to working actually. But sizeof produces the size in bytes. You should switch the int to char.

Since all elements involved are of a size which is a multiple of four, you could do something like this, and still get the same result.

int* adr = (int*)&obj;
for (int i = 0; i < sizeof(obj); i+=4) {*adr = 0; adr += 4;}

Baring any padding the compiler might insert between the fields, for example. It might put each field on a 8 byte / 64 bits region, so access to it is faster.



来源:https://stackoverflow.com/questions/40739415/avoiding-memset-for-a-multi-type-structure

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!