我正在开发一个项目,让我存储一个构造函数为
的对象数组Item(char* item, int itemType){
char temp[200];
for(int i = 0; i < 200; i++){
temp[i] = '\0';
if(item[i] != '\0'){
temp[i] = item[i];
}
}
_item = item;
_itemType = itemType;
_tweetIDs = NULL;
}
不要担心_tweetIDs,这是我程序的另一个功能部分,与我的问题无关。
此数组存储在类中:
ItemList()
这是如何工作的,我的程序的功能部分解析一行输入并将其放入Item(char *,int)对象。这是它添加行的方式:
int addItem(char* item, int type){
char temp1[200];
for(int i = 0; i < 200; i++){
temp1[i] = '\0';
}
int j = 0;
while(item[j] != '\0'){
temp1[j] = item[j];
j++;
}
_items[_size] = Item(temp1, type);
_size++;
return _size;
}
其中_items是Item()数组,_size是每次添加Item()时递增的字段。
当我必须打印列表内容时,我的问题出现了。
我有一个方法可以做到这一点:
void printList(){
for(int i = 0; i < 500; i++){
if(_items[i] != NULL){
cout << "[" << i << "] ";
_items[i]->printContents();
}
}
}
我在Item()的构造函数中测试了printContents(),并在addItem方法中测试了printList,它们在类本身内调用时都有效。当我必须在类体外部调用print方法时,问题出现了。
在main方法中,我创建了一个List对象:
List itemList;
默认构造函数将Item()数组的所有成员设置为NULL并初始化_size。
在数组中添加了几个Item()对象(我确认通过调试器增加了大小),我尝试将其打印出来。我打电话的时候:
itemList.printList();
它为我提供了适量的索引(和行),但是char数组只是一堆垃圾。我使用调试器试图找出它出错的地方。在addItem()方法中,我调用了printList来检查数组,并且从那里输出就可以了。然后,我在最后一次addItem()调用之后调用了itemList.printList(),它给了我垃圾。在addItem()和itemList.printList()之间,char数组丢失或沿着这些行。
知道出了什么问题吗?如果你需要,我会再给你一些代码。
答案 0 :(得分:2)
在您的Item
构造函数中,您正在设置我认为是成员_item
的内容:
_item = item;
这只是将item
指向的位置的指针值分配到_item
。它实际上并不复制字符串!
下次你去阅读这个位置时,它可能是有效的 - 但是,正如你所看到的那样,它很可能是垃圾。
你正在寻找的是像strcpy
这样的函数(作为旁注,没有必要做那么多的手动复制 - 只需将指针传递并复制一次 - 在{{1}中} constructor)。
编辑,以解决您的评论:
Item
导致您的程序崩溃,因为您在未分配的内存中使用它。
您必须使用c ++
中的new[]
为数组分配内存
答案 1 :(得分:1)
记下变量的生命周期。 如果将 temp1 声明为静态数组,则它将在函数 addItem 结束时立即销毁。
最后,引用此内存位置的所有对象都将无效。
并...... 如果要将引用传递给数组,请执行以下操作:
Item(char** item, int itemType)
答案 2 :(得分:0)
在Item
构造函数中创建本地数组char temp[200]
,然后复制char * item
指向的内容,然后再不使用temp[200]
。这样做有什么意义?
稍后您将传递的指针指定给_item
成员。指针指向char temp1[200]
中的局部变量addItem()
。当addItem()
完成后,temp1
将被销毁,因此_item
类中的Item
指向垃圾。
您可能需要做的是在_item
定义中静态分配内存或使用new
动态分配内存(然后不要忘记释放它)。我认为第一个解决方案对您来说更安全。在后一种情况下,您还必须处理复制构造函数和赋值运算符。因此,您需要将_item
定义从char * _item
更改为char _item[200]
,然后才能使用strncpy
:
Item(char* item, int itemType) {
strncpy(_item, item, 200);
}
答案 3 :(得分:0)
我想象你对类Item的定义最低限度如下:
class Item
{
Item(char* item, int itemType);
private:
char *_item;
};
您的构造函数必须为_item分配内存,以便复制通过构造函数传递的内容。如果不这样做将不可避免地导致内存问题和异常。或者,您可以使用类似char的向量。