C ++:该指针指向的变化值 [英] C++: The value that the pointer is pointing to changes

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

问题描述

我试图code,稀土presents一个整数集的一类。这是一个家庭作业,但对我的生活我无法弄清楚这个问题。

在班INTSET,我有两个私有变量;一个是一个指针数组,另一个是所述阵列的大小。我可以创建这个类的对象,他们工作打算。但我有这个功能名为加入,返回INTSET类的一个对象。它本质上并置的阵列可以然后使用该数组来创建返回的对象。

下面是我的code:

 的#include<&iostream的GT;
使用命名空间std;类INTSET {
        INT * arrPtr;
        INT arrSize;
    上市:
        //默认的构造函数
        INTSET(){
            INT ARR [0];
            arrPtr = ARR;
            arrSize = 0;
        }
        //重载的构造函数
        INTSET(INT ARR [],INT大小){
            arrPtr = ARR;
            arrSize =大小;
        }        //拷贝构造函数
        INTSET(常量INTSET和放大器;我){
            arrPtr = i.arrPtr;
            arrSize = i.arrSize;
        }        / *
         *将指针返回到所述第一
         *数组中元素
         * /
        INT * getArr(){
            返回arrPtr;
        }        INT的getSize(){
            返回arrSize;
        }        INTSET加入(INTSET&安培; setAdd){            //创建一个新的数组
            INT温度[arrSize + setAdd.getSize()];            //从当前实例的数组指针添加值
            //到临时数组的开始
            的for(int i = 0; I< arrSize;我++){
                临时[I] ​​= *(arrPtr + I);
            }            //从对象的数组指针传递的添加值
            //到临时数组,但在previously附加值后
            的for(int i = 0; I< setAdd.getSize();我++){
                温度[1 + arrSize] = *(setAdd.getArr()+ I);
            }            //创建一个新的实例,是以临时数组指针和
            //临时数组的大小
            INTSET I(温度,arrSize + setAdd.getSize());            //显示该实例之前,它传递的作品如预期
            COUT<< 在加入的功能:<< ENDL;
            对于(INT J = 0; J< i.getSize(); J ++){
                COUT<< *(i.getArr()+ J)LT;< ENDL;
            }            //返回对象
            返回我;
        }};诠释主(){    //使两个数组
    INT ARR1 [2] = {2,4};
    INT ARR2 [3] = {5,2,7};    //常让两个对象
    INTSET I(ARR1,2);
    INTSETĴ(ARR2,3);
    //这个对象有一个阵列拥有ARR1和ARR2串联,实质上
    //我在这里使用的拷贝构造函数,但如果我改用仍出现问题
    //插图K = i.join(J);
    INTSET K(i.join(J));    //显示错误。这是不相同的值,因为它是被返回之前
    COUT<< 在主要功能:<< ENDL;    为(int类型l = 0; L&下; k.getSize()为:L ++){
        COUT<< *(k.getArr()+ 1)所述;&下; ENDL;
    }    返回0;
}

该程序编译和输出的是现在:

 在加入的功能:
2
4

2
7
在主要功能:
10
0
-2020743083
32737
-2017308032

我不知道为什么,但我每次重新编译和运行时的10和0都是一样的。此外,如果我打印出指针的地址,而不是值(在加入功能和主函数两者)中,我得到相同的存储器地址。

很抱歉,如果我滥用方面,我来自一个Java的背景,所以指针和这样有一点新的我。如果需要任何澄清,请询问。

先谢谢了。


解决方案

  INT温度[arrSize + setAdd.getSize()];

这是一个局部数组,其生命周期结束后的功能恢复。

  INTSET我(温度,arrSize + setAdd.getSize());

在这里,你用这个数组构造一个 INTSET 。事实上构造函数只是改变一个成员指针温度的值:

  INTSET(INT ARR [],INT大小){
    arrPtr = ARR;
    arrSize =大小;
}

其结果是,由于对象的生命周期是温度,因此也 i.arrPtr 指向离开加入后结束,你将有一个野指针。后来在取消引用此指针调用未定义的行为。

您需要用动态分配数组新的[] 后来与删除删除[] 。这同样适用于你的构造。还要注意的是,如果你使用新[] 加入删除[] 在析构函数,那么你还必须确保拷贝构造函数实际上复制阵列(创建新[] 和复制内容)。如果你只是将指针则源和目标对象将指向同一个数组,他们也都将尝试解构删除它,再调用未定义的行为。

不过,由于这个C ++,你还不如用它做这一切为你的std ::矢量。 (或的std ::设置如果你真的想要一个整数集)

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.

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.

Here is my code:

#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

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.

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.

Thanks in advance.

解决方案

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

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

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

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

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.

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.

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天全站免登陆