2010-02-09 130 views
0

我的代码如下:段错误拷贝构造函数

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并在施工图像指针的动态分配的数组。这些指针指向图像。复制构造函数试图对数组中的所有图像进行深层复制。不知何故,我得到一个Segfault,但我不明白我将如何访问数组越界。

任何人都看到什么了吗?

我是新的C++,所以它可能是一些明显。

感谢,

回答

0

我建议MAXNUM(也许图像列表)成为私有数据成员和实施const getMaxnum()setMaxnum()方法。但我怀疑这是你描述这种方式的任何段错误的原因。

我会尝试你参考之前去除常量和落实常量公共方法来提取数据。它可能编译,因为它只是一个参考。另外,我会尝试切换到一个指针,而不是通过引用传递。

或者,可以创建一个单独的场景类对象,并通过图像类型数据作为数组的指针。我不认为你可以声明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); 
0

如果源图像具有比MAXNUM在其图像列表项的实际数目设定得较高,则环路将运行经过source.imagelist数组的末尾。也许当阵列开始是空的(或MAXNUM可能不会得到根本initalized),或者也许如果你有一个场景:: remove_image()函数MAXNUM是越来越初始化为一个,它可能已经删除的图像列表条目不递减MAXNUM。我建议使用std :: vector而不是原始数组。该向量将跟踪自己的大小,因此您的for循环将是:

for(int i=0; i<source.imagelist.size(); i++) 

它只会访问与源矢量保持一样多的项目。崩溃的另一种可能的解释是,source.imagelist中的一个指针属于被删除的映像,但指针从未设置为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值。如果你幸运的话,那么你的程序就会崩溃。如果您直接处理新建和删除操作,请确保在删除指针后将其指针设置为NULL,以便您没有悬挂指针。但是,如果您在某个地方持有指针的副本,则不会阻止此问题,但在这种情况下,当您删除并将NULL复制到第一个副本时,第二个副本不会设置为NULL。如果以后尝试访问指针的第二个副本,则无法知道它不再指向有效的对象。

它是更安全使用智能指针类,并让这种处理内存管理你。标准C++库中有一个名为std :: auto_ptr的智能指针,但它具有奇怪的语义,不能在C++容器中使用,如std :: vector。但是,如果你安装了Boost库,那么我建议用boost :: shared_ptr替换原始指针。