我在网上找不到任何告诉我如何将数据类型放入预分配的内存块的内容。我讨厌自己管理内存,但在这种情况下,我必须这样做。
我有一块10字节长的内存。(我的应用程序是64位使用Visual c。)我想要做的是把1个无符号整型放入字节0-3,把一个char放入[4]和一个char放入[5],再把一个unsigned整型放入[6-9]。
我已经试过了。
所以我正在想办法1)将它存储到这个内存块中,2)检索它
在我看来,实现这一目标的一个好方法是定义一个包含您所描述的数据的结构体:
#pragma pack(1)
struct complex {
uint32_t a; // 4 bytes
char b[2]; // 2 bytes (without paddding)
uint32_t c; // 4 bytes
};
然后你可以简单地填写你的数据:
struct complex var;
var.a = 10;
var.b[0] = 'x';
var.b[1] = 'y';
var.c = 20;
注意#pragma pack(1)
指令告诉编译器使用1字节对齐。如果你不知道它是什么意思,你可以阅读数据结构对齐。
如果不能使用struct
,则应该执行以下操作将数据加载到内存块中。只需执行相反的操作即可取出数据:
// char *mem = <10_bytes>;
unsigned int x = 54;
unsigned int y = 10;
memmove(mem, &x, 4);
memset(mem + 4, 'A', 1);
memset(mem + 5, 'B', 1);
memmove(mem + 6, &y, 4);
您正在处理字节(并且您不存储类型,您只是在其中存储数据)。您可以声明struct
来满足您的需求,或者将数据字节(例如使用memcpy
)复制到适当的位置,例如像
unsigned int lastint;
char* buf;
memcpy (&lastint, buf+6, sizeof(lastint));
但是,要注意,处理这种低级二进制数据会使数据和您的应用程序极其不可移植(并且脆弱,因为当应用程序发展时它会中断)。存在更多的"标准"二进制格式(例如XDR或ASN1)。
-
使用struct
-
(可选)使用编译器特定的"pack"指令来确保编译器不会"填充"任何字段。
-
(可选)使用"memset"(或等效)将块归零
-
每次复制一个字段的数据
PS:Microsoft MSVC和Gnu Gcc都使用"#pragma pack(1)"来防止填充。
你可以使用这个结构体:
#pragma pack(1)
struct TData {
unsigned int a;
char c1;
char c2;
unsigned int b;
};
然后,在你的函数上:
int f()
{
char buffer[10]; // your 10
struct TData *data = (struct TData*)buffer;
printf("a: %d b: %b c1: %c c2: %c", data->a, data->b, data->c1, data->c2);
}