浅copy:
编译器仅仅拷贝了结构体的值,而没有创建新的内存空间,而是共享同一块内存空间。当结构体成员中含有Buf的时候,拷贝之后释放内存就不会出现问题。但是如果结构体中含有指针变量的时候,编译器只会copy指针变量,而对应的内存空间却不会缺不再多分配。
代码:
1 | #define _CRT_SECUFE_NO_WARNINGS |
以此样例为例,输出结果为:
1 | d的值为: |
然后接着某些编译器如vs的编译器就会报错。出错位置为
1 | if (e.c != NULL) { |
这是由于将结构体d内存元素直接赋给结构体e时,即进行 e= d操作时,由于结构体中含有指针元素,d结构体中的指针已经动态分配内存,而操作完成之后e中指针的值也会写上d动态分配内存的地址,因此d和e指向同一内存空间。这样当d中指针d.c释放内存之后,由于e.c仍然指向该部分内存,而不指向空,此时会强制释放掉e.c所指向内存,由于此处内存已经释放过了,处于不能被访问状态,而e.c又强制释放该内存,就会造成vs编译器报错。这就是前copy的弊端。
深copy:
编译器会为拷贝的对象分配一定的内存空间。
以上述代码为例,只需在进行 e= d操作之后再为e.c重新分配内存,然后执行strcpy(e,d)即可。这样e.c和d.c分别指向两块不同的内存,这样就不会出现上面那种错误。
代码:
1 | #define _CRT_SECUFE_NO_WARNINGS |
偏移量的求法
1 | struct note{ |
以p为例求p->age偏移量
直接法
1 | int offsize = (int)&(p->age)-(int)p; |
间接法
1 | int offsize = (int)&(((*note)0)->age); |