假设我有N个字节的连续内存:
char A[N];
| | | | | | | | | | | | | | | | | | | |
我希望像这样访问内存:
|__ _|__ _| | | | | | | | | | | | | | |
前两个块长4个字节,其余块长1个字节。我想基于这个内存创建一个结构,以便以这种方式轻松访问内存。
我试过这种方式,但它不起作用:
typedef struct {
int *a,*b;
char *c;
} mem;
mem *p;
p->a=(int*)A;
p->b=((int*)A+1);
p->c=((int*)A+2);
或
mem *p
p=(mem*)A;
然后使用*(p->a)
,*(p->b)
和*(p->c)
访问元素。
你能否建议我一个正确的方法并向我解释为什么这不起作用?
答案 0 :(得分:0)
试试这个:
#pragma pack(push)
#pragma pack(1)
typedef struct {
int a,b;
char c[256]; // maximum length of `A`
} mem;
#pragma pack(pop)
mem *p = (mem*)A;
答案 1 :(得分:0)
你应该能够这样做:
int* a;
int* b;
char* c;
char A[N] = {/* data goes here */};
a = (int*)A;
b = (int*)(A+sizeof(int));
c = A + 2*sizeof(int);
但是请注意,像这样的不同整数类型之间的类型转换在C中没有明确定义的行为。代码将容易受到字节序的影响,没有人知道签名位最终会在哪里,它可能都会导致陷阱表示等。
因此,除非您的特定编译器保证结果将是什么,否则代码可能会变得混乱。当然它也是不便携的。
编辑:请注意,上面的结构比使用结构指针更便携,尽管结构指针看起来更优雅。因为struct可以在任何地方包含任意数量的填充字节,所以不能保证struc指针会意识到指向的内存是相邻分配的。
答案 2 :(得分:0)
这取决于你想如何对待这块内存 - 即。作为一个整数类型,其中字节序很重要,或者只是一个4个连续字节的块。如果更多 - 那么后者,这就是我接近它的方式:
#include <stdio.h>
typedef struct {
char block[4];
} block_of_4;
typedef struct {
block_of_4 a;
block_of_4 b;
char c[1]; /* hack :) - more legal than "char c[0];" */
} mem;
int main(void)
{
char A[] = "abcdefghijklmnopqrstuvwxyz";
block_of_4 block1 = { { "1234" } };
block_of_4 block2 = { { "9876" } };
mem *p = (mem*) A;
p->a = block1;
p->b = block2;
p->c[2] = '_';
printf("%s\n", A);
return 0;
}
输出:
12349876ij_lmnopqrstuvwxyz
只要编译器决定按顺序保留struct
的元素,并且不进行任何填充,就可以了。
答案 3 :(得分:0)
它不起作用,因为在内存中存储BYTE
和DWORD
的方法不同(在英特尔架构中)。
虽然BYTE
被存储,但DWORD
s以相反的顺序存储
因此,如果您想从1
释放DWORD
作为整数(A[0]
),那么A
必须是:
char A[]={1,0,0,0...}
正如我所见,已经发布了正确的方法。