我的代码如下:
void Scene::copy(Scene const & source)
{
maxnum=source.maxnum;
imagelist = new Image*[maxnum];
for(int i=0; i<maxnum; i++)
{
if(source.imagelist[i] != NULL)
{
imagelist[i] = new Image;
imagelist[i]->xcoord = source.imagelist[i]->xcoord;
imagelist[i]->ycoord = source.imagelist[i]->ycoord;
(*imagelist[i])=(*source.imagelist[i]);
}
else
{
imagelist[i] = NULL;
}
}
}
一点背景:Scene类在构造时有一个名为maxnum的私有int和一个动态分配的Image指针数组。这些指针指向图像。复制构造函数尝试对阵列中的所有图像进行深层复制。不知怎的,我得到了一个Segfault,但我看不出我将如何访问一个超出界限的数组。
有人看错了吗?
我是C ++的新手,所以它可能是显而易见的。
谢谢,
答案 0 :(得分:0)
我建议maxnum(也许是imagelist)成为私有数据成员并实现const getMaxnum()
和setMaxnum()
方法。但我怀疑这是你描述这种情况的任何段错误的原因。
我会尝试在引用之前删除该const并实现const公共方法来提取数据。它可能编译,因为它只是一个参考。此外,我会尝试切换到指针而不是通过引用传递。
或者,您可以创建单独的Scene类对象,并将Image类型数据作为数组指针传递。我认为你不能声明Image *imagelist[value];
。
void Scene::copy(Image *sourceimagelist, int sourcemaxnum) {
maxnum=sourcemaxnum;
imagelist=new Image[maxnum];
//...
imagelist[i].xcoord = sourceimagelist[i].xcoord;
imagelist[i].ycoord = sourceimagelist[i].ycoord;
//...
}
//...
Scene a,b;
//...
b.Copy(a.imagelist,a.maxnum);
答案 1 :(得分:0)
如果源Image的maxnum设置高于其imagelist中的实际项目数,则循环将超过source.imagelist数组的末尾。也许maxnum在数组开始为空时被初始化为值1(或者maxnum可能根本没有被初始化),或者如果你有一个Scene :: remove_image()函数,它可能已经删除了一个没有递减的图像列表条目MAXNUM。我建议使用std :: vector而不是原始数组。向量将跟踪它自己的大小,因此你的for循环将是:
for(int i=0; i<source.imagelist.size(); i++)
并且它只能访问与持有的源向量一样多的项目。崩溃的另一个可能的解释是source.imagelist中的一个指针属于已删除的Image,但指针从未设置为NULL,现在是一个悬空指针。
delete source.imagelist[4];
...
... // If source.imagelist[4] wasn't set to NULL or removed from the array,
... // then we'll have trouble later.
...
for(int i=0; i<maxnum; i++)
{
if (source.imagelist[i] != NULL) // This evaluates to true even when i == 4
{
// When i == 4, we're reading the xcoord member from an Image
// object that no longer exists.
imagelist[i]->xcoord = source.imagelist[i]->xcoord;
最后一行将访问它不应该访问的内存。也许对象仍然存在于内存中,因为它还没有被覆盖,或者它可能已被覆盖并且您将检索无效的xcoord值。如果你很幸运,那么你的程序就会崩溃。如果您直接处理new和delete,请确保在删除指针后将其设置为NULL,这样您就没有悬空指针。但是,如果您在某处保留指针的副本,则不会阻止此问题,在这种情况下,当您删除第一个副本时,第二个副本不会设置为NULL。如果您以后尝试访问指针的第二个副本,您将无法知道它不再指向有效对象。
使用智能指针类更安全,让它为您处理内存管理。标准C ++库中有一个名为std :: auto_ptr的智能指针,但它具有奇怪的语义,不能在C ++容器中使用,例如std :: vector。如果您安装了Boost库,那么我建议用boost :: shared_ptr替换原始指针。