我有一个结构X,它包含一个指向数组的指针:
int global_id = 0;
struct X
{
int id;
char *p;
X(int id_) : p(new char[1024]), id(id_)
{
printf("Constructing X (id %d)\n", id);
}
X() : p(new char[1024]), id(global_id++)
{
printf("Constructing X (id %d)\n", id);
}
~X()
{
delete [] p;
printf("Destroying X (id %d) and array\n", id);
}
X(X const & rhs) : id(global_id++)
{
printf("X copy constructor (%d -> new %d) \n", rhs.id, id);
memcpy(p, rhs.p, sizeof(p));
}
X& operator=(X const & rhs)
{
printf("X copy assignment (%d -> %d) \n", rhs.id, id);
memcpy(p, rhs.p, sizeof(p));
}
X(X && rhs) : id(global_id++)
{
printf("X move constructor (%d -> new %d) \n", rhs.id, id);
swap(p, rhs.p);
}
X& operator=(X && rhs)
{
printf("X move assignment (%d -> %d) \n", rhs.id, id);
swap(p, rhs.p);
}
};
我创建了一个函数foo(),它构造一个本地X并返回它。但它导致了一个段错误:
X foo()
{
X local_x;
return local_x;
}
main()
{
printf("\n1\n");
X x;
printf("\n2\n");
x = foo();
}
我的期望是: 1)构造local_x,打印"构造X(id 1)"
2)将local_x移动到要返回的临时对象中,打印" X移动构造函数(1 - > new 2)"
3)local_x被销毁,打印"销毁X(id 1)"
4)临时移动到x,打印" X移动分配(2 - > 0)"
相反,在local_x的析构函数中发生了段错误:
(gdb) bt
#0 0x00007ffff74ab428 in __GI_raise (sig=sig@entry=6)
at ../sysdeps/unix/sysv/linux/raise.c:54
#1 0x00007ffff74ad02a in __GI_abort () at abort.c:89
#2 0x00007ffff74ed7ea in __libc_message (do_abort=do_abort@entry=2,
fmt=fmt@entry=0x7ffff76062e0 "*** Error in `%s': %s: 0x%s ***\n")
at ../sysdeps/posix/libc_fatal.c:175
#3 0x00007ffff74f9ae8 in malloc_printerr (ar_ptr=0x0, ptr=<optimized out>,
str=0x7ffff7606308 "munmap_chunk(): invalid pointer", action=<optimized out>)
at malloc.c:5004
#4 munmap_chunk (p=<optimized out>) at malloc.c:2840
#5 __GI___libc_free (mem=<optimized out>) at malloc.c:2961
#6 0x0000000000400c8d in X::~X (this=0x7fffffffe220, __in_chrg=<optimized out>)
at ref.cpp:27
#7 0x000000000040098e in foo () at ref.cpp:59
#8 0x0000000000400a4c in main () at ref.cpp:86
(gdb) f 6
#6 0x0000000000400c8d in X::~X (this=0x7fffffffe220, __in_chrg=<optimized out>)
at ref.cpp:27
27 delete [] p;
(gdb) p id
$1 = 1
以下内容打印到stdout:
1
Constructing X (id 0)
2
Constructing X (id 1)
X move constructor (1 -> new 2)
*** Error in `/home/spm/code/ref': munmap_chunk(): invalid pointer: 0x0000000000400edd ***
为什么我会遇到段错误? p应该是指向临时构造函数中使用new []分配的数组的指针,因此delete []应该可以正常工作。
答案 0 :(得分:0)
您的复制构造函数和移动构造函数在其初始化列表中没有python -m pip install SomePackage==3.6.1 # specific version
python -m pip install "SomePackage>=1.0.4" # minimum version
,使它们保持未初始化状态。对于你的拷贝构造函数,这意味着你p
一堆字节到内存中的某个随机点,这是未定义的。对于您的移动构造函数,这意味着当您memcpy
时,您将swap
置于未初始化状态,然后rhs.p
。
对于您的复制构造函数,您可能希望像调用默认构造函数一样调用delete[]
。对于移动构造函数,不需要分配内存;您只需将new
初始化为p
(nullptr
即可安全)。