C++ 中的 char 数组损坏

发布于 2024-12-09 02:57:09 字数 1744 浏览 0 评论 0原文

我正在开发一个项目,该项目使我存储一个对象数组,其构造函数是

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() 之间,字符数组丢失或类似的东西。

知道出了什么问题吗?如果您需要的话,我会给您更多代码。

I'm working on a project that makes me store an array of objects whose constructor is

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;
}

Don't worry about _tweetIDs, that's another functional part of my program and isn't related to my problem.

This array is stored within a class:

ItemList()

How this works is that the functional part of my program parses a line of input and puts it into the Item(char*, int) object. This is how it adds the line:

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;
}

Where _items is the Item() array and _size is a field that is incremented every time an Item() is added.

My issue comes when I have to print the contents of the list.

I have a method that does that:

void printList(){

    for(int i = 0; i < 500; i++){
        if(_items[i] != NULL){
            cout << "[" << i << "] ";
        _items[i]->printContents();
        }
    }
}

I tested printContents() in the constructor of Item() and tested printList in the addItem method and they both work when called within the class itself. The issue comes when I have to call the print method outside the class body.

In the main method, I create a List object:

List itemList;

The default constructor sets all members of the Item() array to NULL and initializes _size.

After adding a few Item() objects into the array (Which I confirmed is increasing in size through the debugger), I tried to print it out. When I call:

itemList.printList();

It gives me the right amount of indexes (And lines), but the char array is just a bunch of garbage. I used the debugger to try and find out where it went wrong. In the addItem() method, I called printList to check the array, and the output from that is fine. Then, I called itemList.printList() right after the last addItem() call, and it gave me garbage. In between the addItem() and itemList.printList(), the char array is lost or something along those lines.

Any idea what's going wrong? I'll give you any more code if you need it.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

红尘作伴 2024-12-16 02:57:09

在您的 Item 构造函数中,您正在设置我认为是成员 _item 的内容:

_item = item;

这只是分配 item 指向的位置的指针值代码> 到 _item。它实际上并不复制字符串!

下次您去阅读此位置时,它可能是有效的 - 不过,正如您所看到的,它很可能是垃圾。

您正在寻找的是一个类似 strcpy (顺便说一句,不需要做太多的手动复制 - 只需在 Item 构造函数中传递该指针并复制一次即可)。

编辑,解决您的评论:

strcpy 使您的程序崩溃,因为您在未分配的内存上使用它。

您必须使用 new[ 为数组分配内存] 在 C++ 中

In your Item constructor, you are setting what I presume is a member _item as such:

_item = item;

This just assigns the pointer value of the location pointed to by item into _item. It does not actually copy the string!

The next time you go to read this location, it might be valid - chances are, though, it will be garbage, as you are seeing.

What you are looking for is a function like strcpy (as a side note, there's no need to do quite so much manual copying - just pass that pointer around and copy it once - in the Item constructor).

EDIT, to address your comment:

strcpy made your program crash because you are using it on unallocated memory.

You have to allocate memory for an array using new[] in c++

知足的幸福 2024-12-16 02:57:09

注意变量的生命周期。
如果将 temp1 声明为静态数组,那么它将在函数 addItem 结束时立即销毁。

最后,所有引用该内存位置的对象都将无效。

和 ....
如果你想传递对数组的引用,可以这样做:

Item(char** item, int itemType)

Take note on the lifetime of a variable.
If you declare temp1 as static array, then it will be destroyed immediately by the end of function addItem.

At the end, all object that refers to this memory location will be invalid.

And ....
If you want to pass a reference to an array do it this way:

Item(char** item, int itemType)
走过海棠暮 2024-12-16 02:57:09

我想象您对类 Item 的定义至少如下所示:

class Item
{
Item(char* item, int itemType);
private:
    char *_item;
};

您的构造函数必须为 _item 分配内存,以便复制通过构造函数传入的内容。如果不这样做将不可避免地导致内存问题和异常。或者,您可以使用诸如 char 向量之类的东西。

I'm imagining your definition of class Item minimally looks like this:

class Item
{
Item(char* item, int itemType);
private:
    char *_item;
};

Your constructor must allocate memory for _item in order to make a copy of what gets passed in via the constructor. Failure to do that will inevitable result in memory problems and exceptions. Alternatively, you can use something like a vector of char.

書生途 2024-12-16 02:57:09

Item 构造函数中,您创建本地数组 char temp[200],然后将 char * item 指向的内容复制到那里,然后就不需要了不再使用 temp[200] 。这样做有什么意义呢?

稍后您将传递的指针分配给 _item 成员。该指针指向addItem() 中的局部变量char temp1[200]。当 addItem() 完成时,temp1 被销毁,因此 Item 类中的 _item 指向垃圾。

您可能需要做的是在 _item 定义中静态分配内存,或者使用 new 动态分配内存(然后不要忘记释放它)。我认为第一个解决方案对你来说会更安全。在后一种情况下,您还必须处理复制构造函数和赋值运算符。因此,您需要将 _item 定义从 char * _item 更改为 char _item[200],然后就可以使用 strncpy< /代码>:

Item(char* item, int itemType) {
    strncpy(_item, item, 200);
}

In Item constructor you create local array char temp[200], you copy there what is pointed by char * item and then you don't use temp[200] any more. What's the point of doing that?

Later you assign passed pointer to _item member. The pointer points to local variable char temp1[200] in addItem(). When addItem() finishes then temp1 is destroyed and so _item in Item class points to garbage.

What you probably need to do is to allocate memory either statically in _item definition or dynamically using new (and then not forget to release it). I think the first solution will be safer for you. In the latter case you would also have to take care of copy constructor and assign operator. So, you need to change _item definition from char * _item to char _item[200], and then you can use strncpy:

Item(char* item, int itemType) {
    strncpy(_item, item, 200);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文