【问题标题】:Initialised arrays showing different values in a loop初始化在循环中显示不同值的数组
【发布时间】:2018-08-10 08:52:11
【问题描述】:

我初始化了一个数组并尝试使用循环和递归来显示元素,但每次它显示的值都与原始值不同。 我尝试单独显示元素,效果很好。

这是定义数组的类定义:

class stack
{
    public:
        int top, *arr;
        stack(int s)
        {
            top=-1;
            size=s;
            arr=def_arr(s);
        }
        void push(int num)
        {
            if(top>=size-1)
            {
                cout<<"Stack has reached maximum length";
            }
            else
            {
                top++;
                arr[top]=num;
            }
        }
        int pop()
        {
            if(top>-1)
            {
                int temp;
                temp=arr[top];
                top--;
                return temp;
            } 
            else
            {
                cout<<"The stack has no values";
            }
        }
        void print()
        {
            if(top>-1)
            {
                for(int i=0; i<=top; i++)
                {
                    cout<<arr[i];
                    cout<<"\t";
                }
            }
            else
            {
                cout<<"Can\'t print stack of length 0";
            }
        }
    private:
        int size;
        int *def_arr(int size)
        {
            int arr[size];
            return arr;
        }
};

以及我运行的代码:

int main()
{
    stack A(3);
    A.push(5);
    A.push(8);
    A.push(10);
    cout<<A.arr[1]<<"\n";
    A.print();
}

结果:

8
5       87      -1259567440               

我错过了什么?

【问题讨论】:

  • def_arr 返回一个悬空指针。 int arr[size] 也是非标准 C++
  • @UnholySheep 你说的非标准是什么意思?
  • 可变长度数组不是 C++ 标准的一部分。一些编译器支持它们作为扩展,但这不是它们所必需的。标准方式是使用std::vector
  • 这就是undefined这个词的美妙之处,它通常会工作一段时间,然后当其他东西试图使用相同的内存时就会停止。

标签: c++ arrays loops recursion c++14


【解决方案1】:
int *def_arr(int size)
    {
        int arr[size];
        return arr;
    }

是错误的,因为它返回一个指向局部变量 arr 的指针。一旦函数退出,局部变量就不再存在,所以指针指向一个无效的地址(也就是一个悬空指针)。使用该指针是未定义的行为。

可变长度数组 (VLA) 是 C++ 中的非标准构造。

两种可能的解决方案

1) 使用 std::vector

#include <vector>

std::vector<int> def_arr(int size)
    {
        std::vector<int> arr(size);
        return arr;
    }

这将需要在您的代码中的其他地方进行更改(主要是您的类中的 arr 也必须重新声明为 std::vector)。

2) 使用动态内存分配

int *def_arr(int size)
    {
        int* arr = new int[size];
        return arr;
    }

这将导致您的代码中出现内存泄漏,修复这些问题并非易事,您应该阅读“三法则”。

大多数人会推荐选项 1。恭喜您即将了解 C++ 中最重要的主题资源管理。

【讨论】:

  • ... is undefined behaviour because it returns a pointer to a local variable arr 技术上 返回指向局部变量的指针本身并不是未定义的。 间接该指针具有未定义的行为。
  • (3) 将所有这些替换为std::stack&lt;int&gt;,避免重新发明轮子。
  • 谢谢,成功了。但是我仍然想知道为什么程序在打印单个元素时有效,但在使用循环执行同一语句时却无效。关于我缺少的循环有什么要了解的吗?
  • 如前所述,其他东西试图使用相同的内存,即你的 for 循环定义了一个整数,它可能已经覆盖了其中一个值,然后你调用 printf,它也可能尝试使用一些你一直在写的内存。所以,有些东西在那里保存了它的数据,这就是你读到的,你的数据被覆盖了。
  • @user8850​​564 未定义的行为是未定义的行为。无论有没有循环,您的程序都有未定义的行为。未定义的行为包括您的程序工作的可能性。这实际上使 C++ 编程变得困难,因为工作程序可能具有未定义的行为,而你不知道,直到它突然停止工作。这正是发生在你身上的事。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-20
  • 2015-12-23
相关资源
最近更新 更多