2016-05-14 106 views
1

我有作业使用动态分配的内存。我的教授给了我一些指示。使用它们,我编码了下面的代码。随机时间出现错误。在执行复制之前有时出现错误。有时它会复制一个对象而不会复制下一个对象。我不明白我做错了什么。动态分配内存,复制构造函数中的错误

默认的构造

GroceryItem::GroceryItem() 
{ 
    item_name = new char[strlen("") + 1]; 
    strcpy(item_name, ""); 
    item_price = 0; 
    qty_on_hand = 0; 
    qty_purchased = 0; 
}; 

功能下面是我用它来复制两个对象的拷贝构造函数:

GroceryItem::GroceryItem(const GroceryItem& Grocery_in) 
{ 
    item_name = new char[strlen(Grocery_in.item_name) + 1]; 
    strcpy(item_name, Grocery_in.item_name); 
    item_price = Grocery_in.item_price; 
    qty_on_hand = Grocery_in.qty_on_hand; 
    qty_purchased = Grocery_in.qty_purchased; 
} 
; 
下面

被分配新建分配FY opperator

GroceryItem& GroceryItem::operator=(GroceryItem& copy_item) 
{ 
    if (this == &copy_item) 
     return *this; 
    else 
    { 
     delete[] item_name; 
     item_name = new char[strlen(copy_item.item_name)+1]; 
     strcpy(item_name, copy_item.item_name); 
     item_price = copy_item.item_price; 
     qty_on_hand = copy_item.qty_on_hand; 
     qty_purchased = copy_item.qty_purchased; 
     return *this ;  // They are the same 
    } 
} 

从函数调用如下当我尝试复制到temp2:

void sort_items(GroceryItem ini_customer_GroceryItem[], int number) 
{ 
    int j = 0, k = 0; 
    GroceryItem temp2; 

    for (j = 0; j < number - 1; j++) // n-1 passes 
    { 
     for (k = number - 1; j < k; k--) // each pass runs one fewer than the preceding one 
     { 
      if (ini_customer_GroceryItem[k - 1] > ini_customer_GroceryItem[k]) 
      { 
       temp2 = ini_customer_GroceryItem[k - 1]; 
       ini_customer_GroceryItem[k - 1] = ini_customer_GroceryItem[k]; 
       ini_customer_GroceryItem[k] = temp2; 
      } 
     } 
    } 
} 

以下是错误

image

+1

你的教授是在帮你帮倒忙通过指示你写陈旧的C代码strcpy()和strlen(),而不是花时间教你真正的C++代码,比如'std :: string',它不需要任何这些废话。为了成为一名熟练的C++开发人员,您没有被教授必要的技能。附:我看到复制构造函数没有错。内存损坏很可能发生在其他地方。仅仅因为你的代码在一个特定的地方崩溃了,也就是拷贝构造函数,并不意味着它就是错误所在。请发布[mcve]。 –

+0

这不是一个拷贝构造函数,它是一个赋值操作符,它应该通过const引用来引用它的参数。“ –

+0

”下面的函数是拷贝构造函数“ - 实际上它是赋值操作符。你的拷贝构造函数在哪里? –

回答

1

sort_items()功能应该使用std::swap()算法,而不是复制手动对象:

/* 
temp2 = ini_customer_GroceryItem[k - 1]; 
ini_customer_GroceryItem[k - 1] = ini_customer_GroceryItem[k]; 
ini_customer_GroceryItem[k] = temp2; 
*/ 
std::swap(ini_customer_GroceryItem[k - 1], ini_customer_GroceryItem[k]); 

无论哪种方式,你没有实现副本构造函数,只有一个复制赋值运算符(和copy_item在您的实施中应为const)。见Rule of Three。您需要实现合适的拷贝构造函数:

GroceryItem::GroceryItem(const GroceryItem& source_item) 
{ 
    item_name = new char[strlen(source_item.item_name)+1]; 
    strcpy(item_name, source_item.item_name); 
    item_price = source_item.item_price; 
    qty_on_hand = source_item.qty_on_hand; 
    qty_purchased = source_item.qty_purchased; 
} 

然后你就可以使用拷贝构造函数实现你的拷贝赋值运算符:

GroceryItem& GroceryItem::operator=(const GroceryItem& copy_item) 
{ 
    if (this != &copy_item) 
    { 
     GroceryItem temp(copy_item); 
     std::swap(temp, *this); 
    } 
    return *this; 
} 

这可以简化为:

GroceryItem& GroceryItem::operator=(GroceryItem copy_item) 
{ 
    std::swap(copy_item, *this); 
    return *this; 
} 

当然,如果你还没有实施过一个,那么别忘了一个破坏者:

GroceryItem::~GroceryItem() 
{ 
    delete[] item_name; 
} 

operator>(),当然,因为sort_items()期待一个。

现在,所有的说,如果你改变了item_name成员是一个std::string代替char*,你将不再需要手动执行析构函数,拷贝构造函数或复制赋值运算符在所有(只是默认构造函数来初始化数字成员)。编译器的默认生成的析构函数的实现,拷贝构造函数和拷贝赋值运算符将足以用于管理所有的数据成员的你:

class GroceryItem 
{ 
public: 
    std::string item_name; 
    float item_price; 
    int qty_on_hand; 
    int qty_purchased; 

    GroceryItem(); 

    bool operator > (const GroceryItem& item) const; 
}; 

GroceryItem::GroceryItem() 
{ 
    item_price = 0.0f; 
    qty_on_hand = 0; 
    qty_purchased = 0; 
}; 

bool GroceryItem::operator > (const GroceryItem& item) const 
{ 
    return ...; 
} 

void sort_items(GroceryItem ini_customer_GroceryItem[], int number) 
{ 
    int j = 0, k = 0; 
    //GroceryItem temp2; 

    for (j = 0; j < number - 1; j++) // n-1 passes 
    { 
     for (k = number - 1; j < k; k--) // each pass runs one fewer than the preceding one 
     { 
      if (ini_customer_GroceryItem[k - 1] > ini_customer_GroceryItem[k]) 
      { 
       /* 
       temp2 = ini_customer_GroceryItem[k - 1]; 
       ini_customer_GroceryItem[k - 1] = ini_customer_GroceryItem[k]; 
       ini_customer_GroceryItem[k] = temp2; 
       */ 
       std::swap(ini_customer_GroceryItem[k - 1], ini_customer_GroceryItem[k]); 
      } 
     } 
    } 
} 
+0

比你所有的评论,我会改变我的代码,看看它的工作。 – kolotei

+0

发现了一些问题与字符代码, 'GroceryItem&GroceryItem ::运算符=(const的GroceryItem&copy_item) { 如果(这种= copy_item!) { GroceryItem温度(copy_item); std :: swap(temp,* this); } return * this; }' – kolotei

+0

你看到什么问题? –

相关问题