结构体常见错误

之前在C语言结构体常见使用方法已经说过结构体其实是对一块空间的划分与使用,那么无论怎么折腾怎么改,都是这一亩三分地,只要找到相应地址,直接改也不奇怪(C的一大核心就是指针和地址)。




1.字符串覆盖其他成员:

简而言之,写入的字符串超出了长度,导致后边的成员被覆盖。

例如这种结构体和操作:

[cpp]  view plain  copy
  1. #include <stdio.h>  
  2. #include <string.h>  
  3.   
  4. typedef struct{  
  5. int iTest;  
  6. char pcArray[20];  
  7. int iParam;  
  8. }s;  
  9.   
  10. main(){  
  11.         s s1;  
  12.         s1.iParam = 5;  
  13.         s1.iTest = 6;  
  14.         printf("iTest:\t%p:%d\n",&s1.iTest,s1.iTest);  
  15.         printf("iParam:\t%p:%d\n",&s1.iParam,s1.iParam);  
  16.         strncpy(s1.pcArray,"Hello World,Hello World",23);  
  17.         printf("pcArray:\t%p:%s\n",&s1.pcArray,s1.pcArray);  
  18.         printf("iTest:\t%p:%d\n",&s1.iTest,s1.iTest);  
  19.         printf("iParam:\t%p:%d\n",&s1.iParam,s1.iParam);  
  20.   
  21.   
  22. }  
结果如下

[cpp]  view plain  copy
  1. [root@j struct]# gcc array.c   
  2. [root@j struct]# ./a.out  
  3. iTest:  0xbfbebc64:6  
  4. iParam: 0xbfbebc7c:5  
  5. pcArray:    0xbfbebc68:Hello World,Hello World  
  6. iTest:  0xbfbebc64:6  
  7. iParam: 0xbfbebc7c:6581362  

因为字符串的超界操作,iParam已经被修改


=========================================================================================================================

补充(20160313):浏览量大,肯定是大家有需求,还是多补点吧。

关于嵌套结构体大小的计算:

关于结构体内部嵌套结构体,有以下两种写法容易产生混淆:

[cpp]  view plain  copy
  1. #include<iostream>  
  2. using namespace std;  
  3. struct ss1{  
  4.         int a;  
  5.         double b;  
  6.         struct aa{  
  7.                 int aa;  
  8.                 double cc;  
  9.         }aa;  
  10.         int c;  
  11. }ss1;  
  12. struct ss2{  
  13.         int a;  
  14.         double b;  
  15.         struct aa{  
  16.                 int aa;  
  17.                 double cc;  
  18.         };  
  19.         int c;  
  20. }ss2;  
  21. int main()  
  22. {  
  23.         cout << sizeof(ss1) << endl;  
  24.         cout << sizeof(ss2) << endl;  
  25.   
  26. }  
前者是在结构体ss1中声明 并定义 了一个aa结构体对象aa,后者只是对结构体类型aa进行了声明,实际不包含,所以ss1与ss2大小不同,差12bytes。




关于C++结构体派生时的对齐优化:

因为派生类空间是在基类部分后边追加的,且互相不侵犯,等于另起炉灶,所以发生派生时,对齐不可优化。

32位,#pragma pack(4),正常情况下(如果前后是正常的,本例前是4bytes的int a,所以是正常对齐的),两个连续声明的char b和char c只占用2bytes(如果后边是个short),考虑到后边的int d,也只不过占用4bytes。但是发生继承时,就不能这样算了:

[cpp]  view plain  copy
  1. #include<iostream>  
  2. using namespace std;  
  3. struct A{  
  4.         int a;  
  5.         char b;  
  6. };  
  7. struct B:A{  
  8.         char c;  
  9.         int d;  
  10.         long long e;  
  11. };  
  12.   
  13. int main(){  
  14.         cout << sizeof(struct A) << endl;  
  15.         cout << sizeof(struct B) << endl;  
  16. }  
中间两个char类型b和c看起来“连着”,实际上因为分属不同的“类部分”所以分别占用4bytes空间,最后B的大小是24,而不是20。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值