Q:

Transferring struct of mixed types to same struct in different memory location

I'm trying to make a small routine that will allow me to make two copies of a struct via pointers and transferring data from one struct to the other only if the other struct contains no data at that point. I am successful with copying the first string over (struct member a) and the second struct member is ok, but the third and fourth are incorrect.
#include "stdio.h"
#include "string.h"

struct A{
    char a[4];
    long b;
    unsigned long c;
    char d;
};

int main(){
    char mb[600];
    struct A *m1=(struct A*)mb;
    char *p=(char*)m1;
    struct A *m2=(struct A*)(mb+100);
    char *pp=(char*)m2;
    memcpy(m1->a,"123",4);
    m1->b=-123;
    m1->c=123;
    m1->d='X';
    m2->b=-456;
    unsigned long q=sizeof(m2);
    while (q-- > 0){
        if (*pp=='\0'){*pp=*p;}
        pp++;p++;
    }
    printf("A=%s B=%ld C=%ld D=%c\n",m2->a,m2->b,m2->c,m2->d);
}

Compilation of the code works fine. When I do run it, I see these results:
A=123 B=-456 C=0 D=

What I'm expecting instead is:
A=123 B=-456 C=123 D=X

I don't want to rewrite the code so that I individually check the value of each member for data. The struct I will work with will be much larger later on and checking each member using strcmp or direct comparison will take up alot of lines of code. I'm looking for something more compact.
What can I do to fix this?
UPDATE:
I changed my code and now tried using this while loop instead of the one above:
    while (q-- > 0){
if (pp[q]=='\0'){pp[q]=p[q];}
}

and the results are still the same (not what I want).

A:

First off, you’re relying on mb being initialized to all zeros, which seems to have happened incidentally when you ran it, but is not guaranteed. If you want it to be initialized to all zeros (and it looks like you do), do that explicitly:
memset(mb, 0, sizeof(mb));

That said, your problem is that you’re only copying sizeof(m2) bytes. m2 is a pointer, so sizeof(m2) is the size of a pointer, not the size of struct A. You probably want sizeof(*m2) instead.

