C ++:指针指向的值发生更改 [英] C++: The value that the pointer is pointing to changes

查看:211
本文介绍了C ++:指针指向的值发生更改的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试编写代表一组整数的类。这是一个家庭作业,但对于我的生活我不知道这个问题。

I am trying to code a class that represents a set of integers. It's a homework assignment but for the life of me I cannot figure out this issue.

在IntSet类中,我有两个私有变量:一个是指向数组的指针,另一个是数组的大小。我可以创建这个类的对象,并按预期工作。但我有一个名为join的函数,返回IntSet类的对象。

In the class "IntSet", I have two private variables; one is a pointer to an array the other is the size of the array. I can create objects of this class and they work as intended. But I have this function named "join" that returns an object of the IntSet class. It essentially concatenates the arrays together then uses that array to create the returning object.

这是我的代码:

#include <iostream>
using namespace std;

class IntSet {
        int * arrPtr;
        int arrSize;
    public:
        //Default Constructor
        IntSet() {
            int arr[0];
            arrPtr = arr;
            arrSize = 0;
        }
        //Overloaded Constructor
        IntSet(int arr[], int size) {
            arrPtr = arr;
            arrSize = size;
        }

        //Copy Constructor
        IntSet(const IntSet &i) {
            arrPtr = i.arrPtr;
            arrSize = i.arrSize;
        }

        /*
         * Returns a pointer to the first
         * element in the array
         */
        int* getArr() {
            return arrPtr;
        }

        int getSize() {
            return arrSize;
        }

        IntSet join(IntSet &setAdd) {

            //Make a new array
            int temp[arrSize + setAdd.getSize()];

            //Add the the values from the current instance's array pointer
            //to the beginning of the temp array
            for (int i = 0; i < arrSize; i++) {
                temp[i] = *(arrPtr + i);
            }

            //Add the values from the passed in object's array pointer
            //to the temp array but after the previously added values
            for (int i = 0; i < setAdd.getSize(); i++) {
                temp[i + arrSize] = *(setAdd.getArr() + i);
            }

            //Create a new instance that takes the temp array pointer and the
            //size of the temp array
            IntSet i(temp, arrSize + setAdd.getSize());

            //Showing that the instance before it passes works as expected
            cout << "In join function:" << endl;
            for (int j = 0; j < i.getSize(); j++) {
                cout << *(i.getArr() + j) << endl;
            }

            //Return the object
            return i;
        }

};

int main() {

    //Make two arrays
    int arr1[2] = {2 ,4};
    int arr2[3] = {5, 2, 7};

    //Make two objects normally
    IntSet i(arr1, 2);
    IntSet j(arr2, 3);


    //This object has an "array" that has arr1 and arr2 concatenated, essentially
    //I use the copy constructor here but the issue still occurs if I instead use
    //Inset k = i.join(j);
    IntSet k(i.join(j));

    //Shows the error. It is not the same values as it was before it was returned
    cout << "In main function:" << endl;

    for (int l = 0; l < k.getSize(); l++) {
        cout << *(k.getArr() + l) << endl;
    }

    return 0;
}

程序编译,现在的输出为:

The program compiles and the output as of now is:

In join function:
2
4
5
2
7
In main function:
10
0
-2020743083
32737
-2017308032

我不知道为什么,但是每次重新编译和运行时,10和0总是相同的。此外,如果我打印出指针的地址而不是值(在连接函数和主函数中),我得到相同的内存地址。

I don't know why but the 10 and 0 are always the same every time I recompile and run. Also, if I print out the address of the pointer rather than the value(in both the join function and the main function), I get the same memory address.

对不起如果我滥用术语,我来自一个java背景,所以指针和这样一个有点新我。如果需要澄清,请询问。

Sorry if I misuse terms, I come from a java background, so pointers and such are a little new to me. If any clarification is needed, please ask.

提前感谢。

推荐答案

int temp[arrSize + setAdd.getSize()];

这是一个局部数组,一旦函数返回,它的生命周期结束。

This is a local array, its lifetime ends once the function returned.

IntSet i(temp, arrSize + setAdd.getSize());

这里你正在构建一个 IntSet 数组。实际上,构造函数只是将一个成员指针更改为 temp 的值:

Here you are constructing an IntSet with this array. In fact the constructor simply changes a member pointer to the value of temp:

IntSet(int arr[], int size) {
    arrPtr = arr;
    arrSize = size;
}

结果,由于 temp ,因此 i.arrPtr 指向结束 join 将有一个野生指针。在 main 中稍后引用此指针将调用未定义的行为。

As a result, since the lifetime of the object that temp and consequently also i.arrPtr is pointing to ends after leaving join, you will have a wild pointer. Dereferencing this pointer later in main invokes undefined behavior.

您需要使用 new [] ,然后使用 delete [] 删除它。你的构造函数也是如此。另请注意,如果您在中使用 new [] 加入 delete [] 在析构函数,那么你还必须确保复制构造函数实际上复制数组(使用 new [] 创建新数组并复制内容)。如果你只是分配指针,那么源和目标对象将指向同一个数组,他们也将尝试在解构时删除它,再次调用未定义的行为。

You need to allocate the array dynamically with new[] and delete it later with delete[]. The same goes for your constructors. Also note that if you use new[] in join and delete[] in the destructor, then you also have to make sure that the copy constructor actually copies the array (create new array with new[] and copy contents). If you simply assign the pointer then both the source and destination object will point to the same array and they will also both try to delete it at deconstruction, again invoking undefined behaviour.

但是自从这个C ++,你可以使用一个 std :: vector ,它为你做这一切。 (或 std :: set ,如果你真的想要一个整数集合)

But since this C++, you might as well use a std::vector which does all of this for you. (or std::set if you actually want a integer set)

这篇关于C ++:指针指向的值发生更改的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆