类型转换结构以获取单个字段地址

时间:2011-08-31 17:57:51

标签: c

#include<stdio.h>
#include<stdlib.h>
struct test{
    char b;
    int a;
    int c ; 
    };
int main()
{
    struct test inst;
    struct test *ptr_test = &inst;
    char * ptr_ch;
    int* ptr_i;

    /*ptr_ch = (char *) ptr_test;*/
    ptr_ch = (char*)ptr_test;
    ptr_i = (int *) ptr_test;
    *ptr_ch = 'b';
    *ptr_i = 13; 

    printf("char b = %c, int a = %d int c = %d", inst.b, inst.a, inst.c);

    return 0;
}

我希望输出给出适当的a,b值和c的垃圾值。 但是在终端上,如果我这样做./a.out输出是:

,int a = 134513785 int c = 13173540

当我做$。/ a.out&gt; TMP; vim tmp,输出为:

char b = ^ M,int a = 134513785 int c = 12714788

有什么问题?

我想使用类型转换访问结构的各个字段。

例如,我想知道另一种返回&amp;(inst.a)值的方法。

5 个答案:

答案 0 :(得分:2)

你的指针

ptr_ch = (char*)ptr_test;
ptr_i = (int *) ptr_test;

不要自动引用第一个适当的成员变量(在你的情况下为b和a)。相反,他们只是将指向结构的指针重新解释为指向charint的指针,因此它们指向相同的位置,即结构的地址。使用char可能很幸运,它是第一个成员,而您确实指向char,但您的int指针指向同一地址,因此,用依赖于平台和编译器的垃圾覆盖它。

所以不要做那些事情(或者当你真正知道自己在做什么时做这些事情,更重要的是,哪里(在什么平台和什么编译器上)你在做什么)。

答案 1 :(得分:1)

ptr_ch和ptr_i指向相同的内存位置:

ptr_ch = (char*)ptr_test;
ptr_i = (int *) ptr_test;

执行以下操作时,您正在读取相同的内存地址:

*ptr_ch = 'b'; //write the first sizeof(char) byte of the structure ptr_test
*ptr_i = 13;   //write the first sizeof(int) bytes of the structure ptr_test overwriting some bytes wrote before

你应该最终做类似的事情:

ptr_ch = &(ptr_test->b);
*ptr_ch = 'b';
ptr_i = &(ptr_test->a);
*ptr_i = 13; 

答案 2 :(得分:0)

为什么要使用类型转换?为什么不这样做:

ptr_ch = &(ptr_test->b);
ptr_i = &(ptr_test->a);

答案 3 :(得分:0)

对于ASCII回车,

13为十进制 - 当您执行*ptr_i = 13;时,您将b设置为13.如果您将打印输出更改为:

printf("char b = %c (%d), int a = %d int c = %d", inst.b, inst.b, inst.a, inst.c);

你会看到你得到:

(13), int a = 1 int c = 1606416024

作为输出。回车符使得char b输出被回车字符后的输出覆盖。如果您使用的数字不同于13,则可能更为明显。例如,使用86,您将得到:

char b = V, int a = 1 int c = 1606416024

作为输出。 ac没有意义的原因是因为它们未被初始化。

您不能只是将结构指针强制转换为另一种类型的指针,并期望编译器为您提取指向该结构中的字段的指针 - 这不是它的工作原理。我想你可能一直试图这样做:

ptr_ch = &ptr_test->b;
ptr_i = &ptr_test->a;

这是一个完整的示例程序,可以完成我认为您正在尝试的内容:

#include<stdio.h>

struct test {
  char b;
  int a;
  int c; 
};

int main(void)
{
  struct test inst = {0, 0, 0};
  struct test *ptr_test = &inst;
  char *ptr_ch;
  int *ptr_i;

  ptr_ch = &ptr_test->b;
  ptr_i = &ptr_test->a;
  *ptr_ch = 'b';
  *ptr_i = 86; 

  printf("char b = %c, int a = %d int c = %d\n", inst.b, inst.a, inst.c);

  return 0;
}

及其输出:

char b = b, int a = 86 int c = 0

答案 4 :(得分:0)

你应该使用严格符合的offsetof macro,它计算struct begin中任何struct元素的偏移量:

 ptr_ch = (char*)ptr_test;
*ptr_ch = 'b';

 ptr_i = ptr_ch + offsetof(struct test,a);
*ptr_i = 13; 
 ptr_i = ptr_ch + offsetof(struct test,c);
*ptr_i = 14;