取消引用结构指针并存储它与指针vs memcpy?

时间:2014-09-24 17:16:16

标签: c pointers

假设我有一个结构

    typedef struct 
    {
        int a;
        int b;
    } s_sample_t;

现在假设我有一个指向结构的指针,

s_sample_t s2 ;
memset (&s2,0,sizeof(s2))
void* s1 = &s2
s_sample_t s3 = *(s_sample_t*)s1;

显然,s1是指向s2的指针。 在为s1取消引用时内存中会发生什么,以及它与

的区别
memcpy(&s3,s1,sizeof(s3));

我们何时应该使用/不使用解除引用?

即应该

s_sample_t s3 = *(s_sample_t*)s1; 
s3.a etc

s_sample_t* s5 = (s_sample_t*)s1;

s5->a etc;

感谢。

2 个答案:

答案 0 :(得分:2)

您的问题分为两部分:

  1. 通常,取消引用结构指针并执行memcpy是一回事。第一个可能更容易阅读,但除此之外,你不应该在两者之间经历太多差异。
  2. 取消引用整个结构(s_sample_t s3 = *(s_sample_t*)s1; ...)会生成结构的副本。取消引用单个字段(s_sample_t* s5 = (s_sample_t*)s1; s5->a;)只能访问您需要的字段。如果您需要复制整个结构,第一个选项通常会更好,因为单个操作几乎肯定比逐个字段复制所有内容更有效。如果您不需要整个结构的副本,使用箭头符号可能会更好,因为您不必复制不必要的内存。

答案 1 :(得分:2)

s3s2的副本(使用memcpy vs dereferencing s1没有区别)因此对s3所做的更改对s2没有影响。 s5是指向s2的指针,因此对s5->a所做的更改将影响s2.a

这里有一些演示此内容的代码

typedef struct
{
    int a;
    int b;
} s_sample_t;

int main( void )
{
    s_sample_t s2 = { 222, 888 };
    void *s1 = &s2;

    // make a copy of s2 by dereferencing s1
    s_sample_t s3 = *(s_sample_t*)s1;
    s3.a = 333;
    printf( "s2.a=%d s2.b=%d\n", s2.a, s2.b );
    printf( "s3.a=%d s3.b=%d\n\n", s3.a, s3.b );

    // make a copy of s2 using memcpy
    s_sample_t s4;
    memcpy( &s4, s1, sizeof(s4) );
    s4.a = 444;
    printf( "s2.a=%d s2.b=%d\n", s2.a, s2.b );
    printf( "s4.a=%d s4.b=%d\n\n", s4.a, s4.b );

    // create a pointer to s2 called s5
    s_sample_t *s5 = s1;
    s5->a = 555;
    printf( "s2.a=%d s2.b=%d\n", s2.a, s2.b );
    printf( "s5->a=%d s5->b=%d\n\n", s5->a, s5->b );
}

在前两种情况下,s2.a的值不受影响,并且会打印222.但在行s5->a = 555;之后,s2.a的值将为555. < / p>