简体   繁体   English

当分配给另一个变量时,C 中的结构中的 malloced 数据会发生什么情况?

[英]What happens to malloced data in a struct in C when it is assigned to another variable?

Let's say I have a structure named "example" which has a member named data which stores data allocated on the heap:假设我有一个名为“example”的结构,它有一个名为 data 的成员,它存储在堆上分配的数据:

typedef struct _EXAMPLE
{
    signed char *data;
    size_t size;
} example_t;

example_t *example_alloc(size_t size)
{
    example_t *ret = malloc(sizeof *ret);
    ret->size = size;
    ret->data = calloc(size, sizeof *ret->data);

    return ret;
}

example_t *a = example_alloc(10), b = *a;

Is the value in b.data stored on the stack or the heap? b.data中的值是存放在栈中还是堆中? Does it point to the data in a ?它是否指向a中的数据?

Pointers are just values.指针只是值。

In the same way that b.size is just a copy of a->size , b.data is a copy of the same pointer value that a->data holds.b.size只是a->size的副本一样, b.dataa->data持有的相同指针值的副本。

It points to the same location, wherever that may be.它指向相同的位置,无论它在哪里。

Care must be taken, as free ing a->data invalidates b.data , and vice versa, which may result in Undefined Behavior if accessed.必须小心,因为free ing a->data会使b.data无效,反之亦然,如果访问,这可能会导致未定义的行为

The structure b is a local variable, and all its members are stored locally in the stack (please, no pedantic comments saying that C doesn't specify that there's a stack -- it requires something that acts like a stack).结构b是一个局部变量,它的所有成员都存储在本地堆栈中(请不要迂腐评论说 C 没有指定有一个堆栈——它需要一些像堆栈一样的东西)。

Since b.data is a member of b , it's stored on the stack.由于b.datab的成员,因此它存储在堆栈中。 However, the data that it points to is the same as what a->data points to, and that's the heap memory that was allocated with calloc() in the function.但是,它指向的数据与a->data指向的数据相同,即在 function 中使用calloc()分配的堆 memory。

Following b = *a , a->data == b.data .b = *a之后, a->data == b.data That is to say they both refer to the same allocated memory. This is known as a " shallow copy ".也就是说,它们都引用相同的分配 memory。这被称为“浅拷贝”。 To achieve a "deep copy" in C would require additional code.要在 C 中实现“深层复制” ,需要额外的代码。 For example:例如:

example_t* example_copy( example_t* b, const example_t* a )
{
    *b = *a ; // shallow copy all members
    
    // Allocate new block and copy content
    size_t sizeof_block = b->size * sizeof(*b->data)
    b->data = malloc( sizeof_block ) ;
    memcpy( b->data, a->data, sizeof_block ) ;

    return b ;
}

Then然后

example_t *a = example_alloc(10) ;
example_t b ;
example_copy( &b, a ) ;

Note that such code is is horribly prone to memory leaks.请注意,此类代码极易发生 memory 泄漏。 Here for example if b goes out of scope before b.data is free 'd, you will have lost access to that memory. Any function that allocates memory and returns without having free 'd it is making it the caller's responsibility whilst not at all making that necessarily visible or obvious (your naming convention _alloc is some level of mitigation perhaps).例如,如果bb.datafree 'd 之前超出 scope,您将无法访问该 memory。任何分配 memory 并在没有free 'd 的情况下返回的 function 都是调用者的责任,但根本不是使它必然可见或明显(您的命名约定_alloc是某种程度的缓解)。 You should at least also implement corresponding functions to facilitate the clean-up of objects.您至少还应该实现相应的功能以方便清理对象。 I appreciate that it is an off-topic point but C++ provides a solution to this issue where a destructor is invoked when an object goes out of scope. Additionally copy constructors and assignment operator overloading can be used to automatically invoke deep-copy semantics.我明白这是一个题外话,但 C++ 提供了一个解决方案,当 object 超出 scope 时调用析构函数。此外,复制构造函数和赋值运算符重载可用于自动调用深度复制语义。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM