【问题标题】:Difference between creating an array in constructor and declaration in c++在构造函数中创建数组和在 C++ 中声明之间的区别
【发布时间】:2014-02-17 20:30:06
【问题描述】:

当我试图在 c++ 类中创建一个数组时,在使用构造函数时出现了一个问题。代码如下:

int stacksize = 100;
int* buffer;
int stackpointer[3]= {-1, -1, -1};
public:
threestack(int stacksize_u)
{
    int buffer_u[stacksize_u*3];
    this->buffer = buffer_u;
    this->stacksize = stacksize_u;
}
threestack()
{
    int buffer_u[(this->stacksize)*3];
    this->buffer = buffer_u;
}

这实际上不起作用。但是,当我在声明中创建数组时,它起作用了:

int stacksize = 100;
int buffer[300];
int stackpointer[3]= {-1, -1, -1};

谁能告诉我在使用构造函数时出了什么问题?

PSS:这是整个课程和测试程序:

class threestack
{
    int stacksize = 100;
    int* buffer;
    int stackpointer[3]= {-1, -1, -1};
public:
    threestack(int stacksize_u)
    {
        int buffer_u[stacksize_u*3];
        this->buffer = buffer_u;
        this->stacksize = stacksize_u;
    }
    threestack()
    {
        int buffer_u[(this->stacksize)*3];
        this->buffer = buffer_u;
    }

    bool push(int stacknum, int value);
    bool pop(int stacknum);
    int peek(int stacknum);
    bool empty(int stacknum);
};

bool threestack::push(int stacknum, int value)
{
    if(stackpointer[stacknum-1]+1 >= stacksize)
    {
        cout<<"Plz do not try to push to a full stack"<<endl;
        //        printf("stackpointer = %d\n", stackpointer[stacknum-1]);
        return 0;
    }
    else
    {
        stackpointer[stacknum-1]++;
        buffer[stackpointer[stacknum-1]+(stacknum-1)*stacksize] = value;
        return 1;
    }
}

int threestack::peek(int stacknum)
{
    if(stackpointer[stacknum-1] < 0)
    {
        printf("No element in stack now.\n");
        return 0;
    }
    else
    {
        printf("stackpointer = %d\n", stackpointer[stacknum-1]);
        return buffer[stackpointer[stacknum-1]+(stacknum-1)*stacksize];
    }
}

bool threestack::pop(int stacknum)
{
    if(stackpointer[stacknum-1] < 0)
    {
        printf("Plz do not try to pop an empty stack.\n");
        return 0;
    }
    else
    {
        stackpointer[stacknum-1]--;
    }
    return 1;
}

bool threestack::empty(int stacknum)
{
    if(stackpointer[stacknum-1] < 0)
    {
        return true;
    }
    else
    {
        return false;
    }
}


int main(int argc, const char * argv[])
{

    threestack test;
    test.push(1,5);
    //    test.pop(1);
    //    test.pop(1);
    int i;
    for(i=0; i<101; i++)
    {
        test.push(2, i);
        printf("%d\n", test.peek(2));
    }
    cout<<endl;
    printf("The top of stack 1 is %d\n", test.peek(1));
    //    std::cout << "Hello, World!\n";
    return 0;
}

【问题讨论】:

  • 请务必发布完整的课程,因为这样真的不是一段编译/有效的代码
  • 你永远不应该持有超出范围的对象指针。构造函数完成后,buffer_u 不再是可以引用的有效内存位置。
  • @crashmstr , thx man,这真的很有帮助,而且很容易理解~
  • @user3320681:另外,打开警告。每个主要的编译器都会发出警告,告诉你问题出在哪里。
  • @MooingDuck 我正在使用 xcode,我想我已经打开了所有警告......但它什么也没说......

标签: c++ arrays constructor declaration


【解决方案1】:

C++ 数组在编译时具有固定大小。 这就是您的测试模块有效的原因 - 大小(=300)在编译时是已知的。 这是强制性的,因为数组的大小实际上是其类型的一部分,这意味着 int[1] 的类型与 int[2] 非常不同。

但不知道您何时在构造函数中“动态”创建数组。 出路是使用newdelete [] 运算符分配动态内存。

更好的是,尝试使用shared_ptr, unique_ptr or auto_ptr

【讨论】:

  • 没有。考虑 newdelete 已弃用。 向初学者推荐它。请改用自动内存管理。
  • new int[10] 创建一个大小在编译时已知的数组。您的意思是完整数组类型的变量具有完整的数组类型(这是重言式),并且数组大小是数组类型的一部分。
  • Thx~ 但是当我在构造函数中创建它时,缓冲区应该指向一个在程序运行时创建的数组,对吗?你的意思是 buffer_u 在编译时被创建为一个固定大小的数组,而不是在运行时被创建为一个 300 大小的数组?
  • @KerrekSB 感谢您的来信!
【解决方案2】:

这个

int* buffer;

不是数组的声明。它是一个指向 int 的指针的声明。

在构造函数中

threestack(int stacksize_u)
{
    int buffer_u[stacksize_u*3];
    this->buffer = buffer_u;
    this->stacksize = stacksize_u;
}

所有这两个语句

    int buffer_u[stacksize_u*3];
    this->buffer = buffer_u;

无效。所有大小的数组中最重要的应该是常量表达式。其次,您将本地数组的第一个元素的地址分配给指针缓冲区。退出构造函数后,该地址将无效,因为本地数组将被销毁。

您应该使用 operator new 动态分配数组并将其值分配给数据成员缓冲区,或者使用容器 std::vector 而不是动态分配的数组。

【讨论】:

    猜你喜欢
    • 2015-02-24
    • 1970-01-01
    • 1970-01-01
    • 2016-01-03
    • 1970-01-01
    • 2013-08-09
    • 2021-10-08
    • 1970-01-01
    • 2011-09-20
    相关资源
    最近更新 更多