简体   繁体   English

浅层副本是否足够用于具有char []的结构?

[英]Is shallow copy sufficient for structures with char[]?

I have a structure containing character arrays with no any other member functions. 我有一个包含字符数组的结构,没有任何其他成员函数。 I am doing assignment operation between two instances of these structures. 我正在这些结构的两个实例之间进行赋值操作。 If I'm not mistaken, it is doing shallow copy. 如果我没有弄错的话,它正在做浅拷贝。 Is shallow copy safe in this case? 在这种情况下,浅拷贝安全吗?

I've tried this in C++ and it worked but I would just like to confirm if this behavior is safe. 我在C ++中尝试了这个并且它有效,但我想确认这种行为是否安全。

If by "shallow copy", you mean that after assignment of a struct containing an array, the array would point to the original struct 's data, then: it can't. 如果通过“浅拷贝”,你的意思是在分配包含数组的struct后,数组将指向原始struct的数据,然后:它不能。 Each element of the array has to be copied over to the new struct . 必须将数组的每个元素复制到新struct "Shallow copy" comes into the picture if your struct has pointers. 如果您的结构有指针,“浅拷贝”会出现在图片中。 If it doesn't, you can't do a shallow copy. 如果没有, 则不能进行浅层复制。

When you assign a struct containing an array to some value, it cannot do a shallow copy, since that would mean assigning to an array, which is illegal. 当您将包含数组的struct分配给某个值时,它不能执行浅表复制,因为这意味着分配给数组,这是非法的。 So the only copy you get is a deep copy. 因此,您获得的唯一副本是深层复制。

Consider: 考虑:

#include <stdio.h>

struct data {
    char message[6];
};

int main(void)
{
    struct data d1 = { "Hello" };
    struct data d2 = d1; /* struct assignment, (almost) equivalent to
                            memcpy(&d2, &d1, sizeof d2) */

    /* Note that it's illegal to say d2.message = d1.message */

    d2.message[0] = 'h';
    printf("%s\n", d1.message);
    printf("%s\n", d2.message);
    return 0;
}

The above will print: 以上将打印:

Hello
hello

If, on the other hand, your struct had a pointer, struct assignment will only copy pointers, which is "shallow copy": 另一方面,如果你的struct有一个指针, struct赋值只会复制指针,这是“浅拷贝”:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct data {
    char *message;
};

int main(void)
{
    struct data d1, d2;
    char *str = malloc(6);
    if (str == NULL) {
        return 1;
    }
    strcpy(str, "Hello");
    d1.message = str;
    d2 = d1;

    d2.message[0] = 'h';
    printf("%s\n", d1.message);
    printf("%s\n", d2.message);
    free(str);
    return 0;
}

The above will print: 以上将打印:

hello
hello

In general, given struct T d1, d2; 一般来说,给定struct T d1, d2; , d2 = d1; d2 = d1; is equivalent to memcpy(&d2, &d1, sizeof d2); 相当于memcpy(&d2, &d1, sizeof d2); , but if the struct has padding, that may or may not be copied. ,但如果结构有填充,可能会或可能不会被复制。

Edit : In C, you can't assign to arrays . 编辑 :在C中,您无法分配给数组 Given: 鉴于:

int data[10] = { 0 };
int data_copy[10];

data_copy = data;

is illegal. 是非法的。 So, as I said above, if you have an array in a struct , assigning to the struct has to copy the data element-wise in the array. 因此,正如我上面所说,如果在struct有一个数组,则分配给结构必须在数组中按元素方式复制数据。 You don't get shallow copy in this case: it doesn't make any sense to apply the term "shallow copy" to a case like this. 在这种情况下,您不会得到浅层副本:将“浅层副本”一词应用于此类案例没有任何意义。

Assigning structs does a member-wise assignment, and for arrays this means assigning each item. 分配结构执行成员分配,对于数组,这意味着分配每个项目。 (And this is done recursively for "multiple dimension" arrays, which are really just arrays of arrays.) (这是针对“多维”数组递归完成的,这些数组实际上只是数组的数组。)

You are correct that it does a shallow copy, even on arrays. 你是正确的,它做一个浅拷贝,甚至在数组上。 (I'm assuming that you have not overloaded op= with respect to C++; if you overload it you can do anything you want.) (我假设你没有重载op =关于C ++;如果你超载它你可以做你想做的任何事。)

Remember that a shallow copy means copying the value of something, while a deep copy means copying the value to which something points or refers. 请记住,浅拷贝意味着复制某些东西的值,而深拷贝则意味着复制某些东西指向或引用的值。 The value of an array is each item in it. 数组的值是其中的每个项目。

The difference between shallow and deep is most meaningful when you have a type that does indirection, such as a pointer. 当你有一个间接的类型,例如指针时,浅和深之间的区别是最有意义的。 I find my answer the most helpful way to look at this issue, but you could also say "shallow" vs "deep" doesn't even apply to other types, and they are just "copied". 我发现我的答案是看待这个问题的最有用的方法,但你也可以说“浅”和“深” 甚至不适用于其他类型,它们只是“复制”。

struct S {
  int n;
  int* p;
  int a[2];
  int* ap[2];
  int xy[2][2];
};

void f() {
  S c, d;

  c = d;
  // equivalent to:
  c.n = d.n;
  c.p = d.p;

  c.a[0] = d.a[0];  // S::a is similar to your situation, only using
  c.a[1] = d.a[1];  // int instead of char.

  c.ap[0] = d.ap[0];
  c.ap[1] = d.ap[1];
  c.xy[0][0] = d.xy[0][0];
  c.xy[0][1] = d.xy[0][1];
  c.xy[1][0] = d.xy[1][0];
  c.xy[1][1] = d.xy[1][1];
}

That I used int above doesn't change anything of the semantics, it works identically for char arrays, copying each char. 我在上面使用int并没有改变任何语义,它对char数组的工作方式相同,复制每个char。 This is the S::a situation in my code. 这是我的代码中的S :: a情况。

Note that p and ap are copied shallowly (as is every other member). 请注意, pap被浅层复制(与其他所有成员一样)。 If those pointers "own" the memory to which they point, then it might not be safe. 如果这些指针“拥有”它们指向的内存,那么它可能不安全。 ("Safe" in your question is vague, and really depends on what you expect and how you handle things.) (你问题中的“安全”是模糊的,实际上取决于你的期望和处理方式。)

For an interesting twist, consider boost::shared_ptr and other smart pointers in C++. 有趣的是,请考虑使用C ++中的boost :: shared_ptr和其他智能指针。 They can be copied shallowly, even though a deep copy is possible, and this can still be safe. 它们可以被浅层复制,即使可以进行深层复制,这仍然是安全的。

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

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