0

I have an old piece of code with a big struct that looks like this:

typedef struct {
 long test1;
 char test2[10]
 …
} teststruct;

This struct gets initialized like this:

memset(teststruct, 0, sizeof(teststruct0));

I must not change this code in any way. How do I efficiently check if the struct is empty, or has been modified after the memset()?

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Zeta
  • 11
  • 3
  • 1
    What do you mean by "empty"? It has member variables, so it cannot be empty. Do you mean to check if all the values are still set to 0? – UnholySheep Nov 26 '21 at 09:22
  • 1
    Have a boolean flag that you set to true if you set some values in the structure? And if that's not possible, `memcmp` with a structure which is "empty"? – Some programmer dude Nov 26 '21 at 09:22
  • What do you mean by "struct is empty" – justANewb stands with Ukraine Nov 26 '21 at 09:23
  • 2
    You can `memcmp` with an array of zeros of the same size. – Henri Menke Nov 26 '21 at 09:23
  • 2
    Why `memset`? Btw, `teststruct` is not an instance. It's a _type_ so `memset(teststruct, 0, sizeof(teststruct));` is utterly wrong. – Ted Lyngmo Nov 26 '21 at 09:25
  • I need to check if no entries have been changed since the memset, thats what I mean with „empty“. – Zeta Nov 26 '21 at 09:28
  • @molbdnilo But `memset` will also set the padding. – Some programmer dude Nov 26 '21 at 09:29
  • I am not allowed to make a boolean flag. This above was just an example, the actual struct type has over 600 lines and is about 20 years old. – Zeta Nov 26 '21 at 09:31
  • @Zeta Is it compiled with a C++98 compiler? How is it instantiated and how is `memset` really used? – Ted Lyngmo Nov 26 '21 at 09:34
  • Is `test2` a null terminated C string or just an array of 10 `char`s (not forming a string)? – Ted Lyngmo Nov 26 '21 at 09:42
  • Can you show the actual code? The code you posted cannot work, since teststruct is a typedef and not a variable. You can leave out all the lines in the struct, but please show the rest. – Benedict H. Nov 26 '21 at 09:42
  • The code was originally written in Pascal and later on ported to C++. Now it gets compiled with a C++11 compiler. The memset is used exactly as stated above with an instance of the struct. I must not change the struct and the memset since this code is used in a very critical application and must not be changed by anyone. – Zeta Nov 26 '21 at 09:47
  • test2 is forming a c string – Zeta Nov 26 '21 at 09:48
  • "_The memset is used exactly as stated above_" - no, that will not compile since you have put a _type_ where a pointer to memory should have been put. – Ted Lyngmo Nov 26 '21 at 09:51
  • Sorry for the typo, I forgot that I already got a pointer here, I just copied it off 1:1 and changed the names. – Zeta Nov 26 '21 at 10:01
  • A lot of these comments feel needlessly pedantic or irrelevant to the question at hand. Since you are unable to store an additional modified flag, can this question be restated as checking if the current contents of a given `teststruct` are identical to that of a new `teststruct` directly after being initialized with `memset`? – Locke Nov 26 '21 at 10:04
  • Update the question instead of explaining in the comment section – Ted Lyngmo Nov 26 '21 at 10:05
  • @Zeta If you've set `test2` to something, like `teststruct i; memset(&i, 0, sizeof i); strcpy(i.test2, "Hello");` and then set it back to a blank string: `strcpy(i.test2, "");` should `i` now be considered _empty_ again? – Ted Lyngmo Nov 26 '21 at 10:24

1 Answers1

3

It sounds like what you want is to find out if this struct has any non-zero values. As you can see in the comments, there are a couple exceptions you may want to consider, but for the simple solution we can copy this previous answer.

// Checks if all bytes in a teststruct are zero
bool is_empty(teststruct *data) {
    unsigned char *mm = (unsigned char*) data;
    return (*mm == 0) && memcmp(mm, mm + 1, sizeof(teststruct) - 1) == 0;
}
Locke
  • 7,626
  • 2
  • 21
  • 41