【发布时间】:2013-08-07 10:27:10
【问题描述】:
例如,这让我很困惑:
struct A {
// some fileds...
char buf[SIZE];
};
A a;
a = a;
通过A的字段buf,看起来可能默认的赋值操作会调用memcpy之类的东西来将对象X赋值给Y,那么如果将对象赋值给自己并且没有定义明确的赋值操作怎么办,比如上面的a = a;。
memcpy 手册页:
DESCRIPTION
The memcpy() function copies n bytes from memory area src to memory area dest. The memory areas must not overlap. Use memmove(3) if the memory areas do overlap.
如果使用memcpy,可能会出现一些未定义的行为。
那么,C++ 对象中默认的赋值操作行为是什么?
【问题讨论】:
-
重叠的问题是,如果您从一个被该区域的另一部分覆盖的区域复制 - 也就是说,您将一个字符插入到字符串中,然后执行
memcpy(&a[index+1], &a[index], len-index);。但是memcpy(a, a, sizeof(a))会很好。 -
@R.MartinhoFernandes 你能这么好心告诉我那个例外是什么吗?
-
@nijansen 这是字符串文字。
"bar"和"foobar"是可以重叠存储的一对文字的示例。 (在这种情况下这不是问题,因为这些数组是const。) -
@MatsPetersson memcpy(a, a, sizeof(a)) 不好,src 和 dst(完全)重叠。
-
好吧,让我换个说法:它可能是未定义的,但重叠区域的危险不是当重叠完成时,也就是说,你正在将东西从位置 X 复制到位置 X,但是当源和目标之间存在偏移时,源、源+长度和目标、目标+长度重叠,因为目标的写入将在某些时候覆盖源。如果您直接覆盖,则导致问题的可能性要小得多。当然,在自身上复制 200 个字节也是完全浪费时间。