繁体   English   中英

没有指针的 C++ 中的动态 memory 分配 - 指针有什么意义?

[英]dynamic memory allocation in C++ without pointers - what's the point of pointers?

考虑以下 C++ 程序:

#include <iostream>
using namespace std;

void printArray(int p_values[], int size, int elements_set);

int main() 
{
    int next_element = 0;
    int size = 3;
    int p_values[size]; 
    int val;
    cout << "Please enter a number: ";
    cin >> val;

    while (val > 0)
    {
    if (size == next_element+1)
    {
        size *=2;
        int p_values[size];
    }
    p_values[next_element] = val;
    next_element++;
    cout << "Current array values are: " << endl;
    printArray(p_values, size, next_element);
    cout << "Please enter a number (or 0 to exit): ";
    cin >> val;
    }   

}


void printArray(int p_values[], int size, int elements_set) 
{
cout << "Total size of array: " << size << endl;
cout << "Number of slots set so far: " << elements_set << endl;
cout << "Values in the array: " << endl;
    for (int i = 0; i < elements_set; ++i){
        cout << "p_values[" << i << "] = "
             << p_values[i] << endl;
    }
}

代码的作用很简单: 1. 要求用户输入数字 2. 数字保存在数组中 3. 打印出数组的当前内容

一旦数组满了,它的大小就会加倍。 这种在运行时动态增加数组通常是用指针来完成的。 事实上,有人告诉我,只有使用指针才能动态增加数组大小。

但是,正如您在上面的程序中看到的那样,我没有使用任何指针,而只使用了 static 数组。 然而,程序会在运行时动态增加数组的大小。

因此,我的问题是: 1. 为什么我在大学(以及几本书中)被告知,在 C++ 程序中,只有通过使用指针才能在运行时增加 memory 的使用? 2. 考虑到动态 memory 分配可以在没有它们的情况下完成,指针有什么意义(除了可以在调用函数时通过引用传递变量)?

程序运行一段时间,输入8个数字后,程序的output如下:

Please enter a number (or 0 to exit): 8
Current array values are: 
Total size of array: 12
Number of slots set so far: 8
Values in the array: 
p_values[0] = 1
p_values[1] = 2
p_values[2] = 3
p_values[3] = 4
p_values[4] = 5
p_values[5] = 6
p_values[6] = 7
p_values[7] = 8
Please enter a number (or 0 to exit): 
    size *=2;
    int p_values[size];
}

不。 这不会增加在函数开头声明的现有p_values数组的大小。 这在内部范围内声明了另一个名为p_values数组。

...并且由于内部作用域立即在此处结束,因此这没有任何作用。 循环继续进行并从原始p_values数组的末尾开始运行,从而导致未定义的行为和内存损坏。

但是,程序会在运行时动态增加数组的大小。

不,不是。 现有阵列的大小没有动态增加。 在内部范围中声明了另一个更大的可变长度数组,并立即将其销毁。 原始数组保持其原始大小,并导致未定义的行为。

只是继续向数组中输入更多的值,在某个时候,您将最终破坏堆栈上的返回地址,从而在main()返回时导致segfault(假设编译器通过调整的大小来动态实现可变长度数组)当前函数的堆栈框架)。

事实上

int size = 3;
int p_values[size]; 

无效的C ++。 此功能(可变长度数组)是在1999年标准中引入到C中的,并且不在任何C ++标准中,或者建议添加。 一些C ++编译器(和早于1999 C标准的某些C编译器)支持此功能作为非标准扩展。

即使我们假设编译器支持C的VLA,这

int size = 3;
int p_values[size]; 

/* other code */
{
    size *=2;
    int p_values[size];
}

不调整p_values大小。 它在嵌套作用域内(即{} )临时创建了另一个不在作用域外的数组。

您的代码无效。 您的“重新分配”没有任何作用-您正在创建另一个遮蔽名称的数组。 同时,您正在覆盖的内存不是您的内存(例如,p_values [9]是存储size变量的位置)。 继续前进,就会变得更加清楚:

Please enter a number: 1
Current array values are:
Total size of array: 3
Number of slots set so far: 1
Values in the array:
p_values[0] = 1
Please enter a number (or 0 to exit): 2
Current array values are:
Total size of array: 3
Number of slots set so far: 2
Values in the array:
p_values[0] = 1
p_values[1] = 2
Please enter a number (or 0 to exit): 3
Current array values are:
Total size of array: 6
Number of slots set so far: 3
Values in the array:
p_values[0] = 1
p_values[1] = 2
p_values[2] = 3
Please enter a number (or 0 to exit): 4
Current array values are:
Total size of array: 6
Number of slots set so far: 4
Values in the array:
p_values[0] = 1
p_values[1] = 2
p_values[2] = 3
p_values[3] = 4
Please enter a number (or 0 to exit): 5
Current array values are:
Total size of array: 6
Number of slots set so far: 5
Values in the array:
p_values[0] = 1
p_values[1] = 2
p_values[2] = 3
p_values[3] = 4
p_values[4] = 5
Please enter a number (or 0 to exit): 6
Current array values are:
Total size of array: 12
Number of slots set so far: 6
Values in the array:
p_values[0] = 1
p_values[1] = 2
p_values[2] = 3
p_values[3] = 4
p_values[4] = 5
p_values[5] = 6
Please enter a number (or 0 to exit): 7
Current array values are:
Total size of array: 12
Number of slots set so far: 7
Values in the array:
p_values[0] = 1
p_values[1] = 2
p_values[2] = 3
p_values[3] = 4
p_values[4] = 5
p_values[5] = 6
p_values[6] = 7
Please enter a number (or 0 to exit): 8
Current array values are:
Total size of array: 12
Number of slots set so far: 8
Values in the array:
p_values[0] = 1
p_values[1] = 2
p_values[2] = 3
p_values[3] = 4
p_values[4] = 5
p_values[5] = 6
p_values[6] = 7
p_values[7] = 8
Please enter a number (or 0 to exit): 9
Current array values are:
Total size of array: 12
Number of slots set so far: 10
Values in the array:
p_values[0] = 1
p_values[1] = 2
p_values[2] = 3
p_values[3] = 4
p_values[4] = 5
p_values[5] = 6
p_values[6] = 7
p_values[7] = 9
p_values[8] = 10
p_values[9] = 12
Please enter a number (or 0 to exit): 11
Current array values are:
Total size of array: 12
Number of slots set so far: 11
Values in the array:
p_values[0] = 1
p_values[1] = 2
p_values[2] = 3
p_values[3] = 4
p_values[4] = 5
p_values[5] = 6
p_values[6] = 7
p_values[7] = 11
p_values[8] = 11
p_values[9] = 12
p_values[10] = 11
Please enter a number (or 0 to exit): 12
Current array values are:
Total size of array: 24
Number of slots set so far: 12
Values in the array:
p_values[0] = 1
p_values[1] = 2
p_values[2] = 3
p_values[3] = 4
p_values[4] = 5
p_values[5] = 6
p_values[6] = 7
p_values[7] = 12
p_values[8] = 12
p_values[9] = 24
p_values[10] = 11
p_values[11] = 12
Please enter a number (or 0 to exit): 13
Current array values are:
Total size of array: 24
Number of slots set so far: 13
Values in the array:
Segmentation fault (core dumped)

相同表示的数组的嵌套定义,而不是动态重新分配,证明对明显意图无效并最终由于解除管制的输入而导致 memory 损坏。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM