C ++中的char数组损坏

时间:2011-10-10 01:28:21

标签: c++ arrays printing char cout

我正在开发一个项目,让我存储一个构造函数为

的对象数组
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数组丢失或沿着这些行。

知道出了什么问题吗?如果你需要,我会再给你一些代码。

4 个答案:

答案 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的向量。