枚举内存状况

 #define SALFDELETE(pValue) /
 if (pValue) /
  delete[] pValue; /
 pValue = NULL;

struct stuMemInfo
{
 void    *pAllocAddr;
 wchar_t *pPageInitProtect;
 DWORD    dwReginSize;
 DWORD    dwState;
 wchar_t  *pStateInfo;
 wchar_t  *pPageProect;
 wchar_t  *pPageType;

};

void PageProtectToString(DWORD dwProtect, wchar_t *pContent)
{
 if (!pContent)
 {
  return;
 }

  switch (dwProtect)
  {
   case PAGE_EXECUTE:
    {
     wsprintfW(pContent, L"E---");

     break;
    }
   case PAGE_EXECUTE_READ:
    {
     wsprintfW(pContent, L"ER--");

     break;
    }
   case PAGE_EXECUTE_READWRITE:
    {
     wsprintfW(pContent, L"ERW-");

     break;
    }
   case PAGE_EXECUTE_WRITECOPY:
    {
     wsprintfW(pContent, L"ERWC");

     break;
    }
   case PAGE_NOACCESS:
    {
     wsprintfW(pContent, L"----");

     break;
    }
   case PAGE_READONLY:
    {
     wsprintfW(pContent, L"-R--");

     break;
    }
   case PAGE_READWRITE:
    {
     wsprintfW(pContent, L"-RW-");

     break;
    }
   case PAGE_WRITECOPY:
    {
     wsprintfW(pContent, L"---C");

     break;
    }
   case PAGE_GUARD:
    {
     wsprintfW(pContent, L"page guard");

     break;
    }
   case PAGE_NOCACHE:
    {
     wsprintfW(pContent, L"page no catch");

     break;
    }
  }
}

int _tmain(int argc, _TCHAR* argv[])
{
 SYSTEM_INFO mySysInfo;
 memset(&mySysInfo, 0, sizeof(SYSTEM_INFO));
 GetSystemInfo(&mySysInfo);
 DWORD pageSize = mySysInfo.dwAllocationGranularity;

 BYTE *pBasicAddr = NULL;
 MEMORY_BASIC_INFORMATION memBasicInfo;

 setlocale(LC_CTYPE, "");
 wchar_t *pMemInfo = new wchar_t[512];
 memset(pMemInfo, 0, sizeof(512));
 stuMemInfo memInfo;
 memset(&memInfo, 0, sizeof(stuMemInfo));

 memInfo.pStateInfo = new wchar_t[50];
 memInfo.pPageInitProtect = new wchar_t[20];
 memInfo.pPageProect = new wchar_t[50];
 memInfo.pPageType = new wchar_t[50];

 do
 {
  memset(&memBasicInfo, 0, sizeof(memBasicInfo));
  if ( VirtualQuery(pBasicAddr, &memBasicInfo, sizeof(MEMORY_BASIC_INFORMATION)) == NULL)
  {
   break;
  }
  

  if (memBasicInfo.State == MEM_FREE)
  {
   wprintf(L"the addr %p is MEM_FREE /r/n", pBasicAddr);
   pBasicAddr += memBasicInfo.RegionSize;
   continue;   
  }

  memInfo.dwState = memBasicInfo.State;

  switch (memBasicInfo.State)
  {
  case MEM_COMMIT:
   {
    wsprintfW(memInfo.pStateInfo, L"memory state is MEM_COMMIT");

    break;
   }
  case MEM_RESERVE:
   {
    wsprintfW(memInfo.pStateInfo, L"memory state is MEM_RESERVE");

    break;
   }
  }


  PageProtectToString(memBasicInfo.AllocationProtect, memInfo.pPageInitProtect);

  memInfo.dwReginSize = (DWORD) memBasicInfo.RegionSize;

  if (memBasicInfo.State != MEM_RESERVE)
  {
   PageProtectToString(memBasicInfo.Protect, memInfo.pPageProect);
  }
  else
  {
   wcscpy(memInfo.pPageProect, L"MEM_RESERVE");
  }

  switch (memBasicInfo.Type)
  {
  case MEM_IMAGE:
   {
    wsprintfW(memInfo.pPageType, L"MEM_IMAGE");

    break;
   }
  case MEM_MAPPED:
   {
    wsprintfW(memInfo.pPageType, L"MEM_MAPPED");

    break;
   }
  case MEM_PRIVATE:
   {
    wsprintfW(memInfo.pPageType, L"MEM_PRIVATE");

    break;
   }

  }

  memInfo.pAllocAddr = memBasicInfo.AllocationBase;

  wprintf(L"the BaseAddress is %p, AllocationBase is %p, PageState is %s,/
    InitProtect is %s, current Protect is %s, type is %s, /
    page number is %d /r/n",
    pBasicAddr, memInfo.pAllocAddr, memInfo.pStateInfo,
    memInfo.pPageInitProtect, memInfo.pPageProect,
    memInfo.pPageType, memInfo.dwReginSize);

  pBasicAddr += memInfo.dwReginSize;

 } while (1);

 SALFDELETE(memInfo.pPageType);
 SALFDELETE(memInfo.pPageProect);
 SALFDELETE(memInfo.pPageInitProtect);
 SALFDELETE(memInfo.pStateInfo);
 
 getchar();

 return 0;
}

<think>好的,用户问的是结构体和枚举内存计算。我需要先回忆一下C/C++中结构体和枚举内存对齐规则。结构体的内存对齐是为了提高访问效率,通常会根据成员变量的类型进行对齐。比如,一个结构体里有char和int,那么char可能会被填充到4字节对齐,导致结构体总大小为8字节。而枚举内存占用通常取决于其底层类型,默认情况下,枚举的大小可能等于int的大小,但具体还要看编译器实现和是否指定了底层类型。 接下来,我需要给出结构体和枚举内存计算的例子。对于结构体,可以举一个包含不同数据类型的例子,并说明对齐后的总大小。比如structMyStruct { chara; int b; char c;}; 在32位系统中,每个成员的对齐要求是char为1字节,int为4字节。所以a占用1字节,后面填充3字节到4的倍数,然后b占4字节,c占1字节,再填充3字节到总大小为12字节?或者是不是更优化的排列方式?或者用户可能想问的是编译器是否会重新排列成员变量以减少填充?比如调整成员的顺序,把大的成员放在前面,可能减少填充。比如struct MyStruct {int b; chara; char c; }; 这样总大小会是8字节,因为int占4,两个char各占1,填充2字节到4的倍数,总大小8。所以结构体成员的顺序会影响内存占用。 然后对于枚举,比如enumMyEnum { A, B, C}; 在C++中,默认情况下可能占用4字节,但如果有更大的值,比如超过int的范围,可能会用更大的类型。或者如果指定了底层类型,比如enum MyEnum: uint8_t{ ... };则大小为1字节。 需要给出具体的例子代码,并计算它们的大小。比如用sizeof操作符来展示结构体和枚举的大小。然后解释为什么是这个结果,涉及对齐规则。 然后可能的问题包括结构体对齐的规则,如何减少内存占用,枚举底层类型的指定方法,以及不同编译器是否有不同的处理方式等。</think>结构体和枚举内存计算主要涉及内存对齐机制和类型尺寸计算,以下是详细说明和示例: ### 一、结构体内存计算 ```c #include <stdio.h> struct Example1 { char a; // 1字节 int b; // 4字节 short c; // 2字节 }; // 总尺寸可能为12字节 struct Example2 { int b; // 4字节 char a; // 1字节 short c; // 2字节 }; // 总尺寸可能为8字节 int main() { printf("Sizeof Example1: %zu\n", sizeof(struct Example1)); printf("Sizeof Example2: %zu\n", sizeof(struct Example2)); return 0; } ``` **内存对齐规则**: 1. 结构体起始地址=最宽成员对齐值的整数倍 2. 成员偏移量=成员类型大小的整数倍 3. 结构体总大小=最大对齐值的整数倍 **示例分析**: - `Example1`: - char(1) + 3填充 → int(4) → short(2) + 2填充 → 总大小12 - `Example2`: - int(4) → char(1) + 1填充 → short(2) → 总大小8 ### 二、枚举内存计算 ```c #include <stdio.h> enum SmallEnum { A, B, C }; // 通常占4字节 enum BigEnum { D = 0xFFFFFFFFFFFFFFFF }; // 可能占8字节 int main() { printf("Small enum size: %zu\n", sizeof(enum SmallEnum)); printf("Big enum size: %zu\n", sizeof(enum BigEnum)); return 0; } ``` **枚举尺寸规则**: 1. 默认尺寸由编译器决定(通常为int大小) 2. C11/C++11支持指定底层类型: ```c enum MyEnum : uint8_t { X, Y, Z }; // 显式指定1字节 ``` ### 三、优化建议 1. 结构体成员按从大到小排序 2. 合理使用`#pragma pack`修改对齐系数 3. 对枚举显式指定底层类型
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值