2016-11-19 85 views
0

考虑下面的C++程序:无指针的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的当前内容阵列打印出来

一旦阵列满了,它的大小加倍。 运行时数组的这种动态增加通常使用指针完成。实际上,我被告知只能通过使用指针来实现数组大小的这种动态增加。

但是,正如你在上面的程序中看到的,我没有使用任何指针,而只使用静态数组。尽管如此,该程序在运行时动态增加了数组的大小。

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

在已经运行的程序的一个,同时与已进入8个数字,该方案的输出如下所示:

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): 
+2

公平地说,这不是一个C++程序。 VLA不是C++的一部分。 – krzaq

+0

指针指向的东西。事情如何分配是另一回事。 – juanchopanza

+0

如果我可以问,什么是VLA? –

回答

8
size *=2; 
    int p_values[size]; 
} 

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

...并且由于内部范围立即在此结束,所以这没有任何影响。循环继续进行,并在原始的p_values数组末尾运行,导致未定义的行为和内存损坏。

尽管如此,程序在运行时动态增加了数组的大小 。

不,它没有。现有阵列的大小不会动态增加。一个不同的,更大的变长数组在内部范围内声明,并立即销毁。原始数组保持其原始大小,并导致未定义的行为。如果你的编译器动态地通过调整它的值来动态地实现可变长度的数组,那么你会最终在堆栈中砸碎返回地址,导致段错误(假设你的编译器动态地实现了可变长度的数组)当前函数堆栈帧的大小)。

+0

@Varshachik ...所以新阵列的内存位置不是(!)旧阵列的内存位置加上一些额外的内存?换句话说:新数组的第一个元素与旧数组的第一个数值位于完全不同的存储单元中? ...此外,旧阵列使用的内存空间未被释放,所以我的程序导致内存泄漏? –

+0

不,这两个数组是完全独立的对象,无论如何都与彼此无关。另外,没有内存泄漏。只要没有未定义的行为发生,新阵列和旧阵列的内存都会在其各自的作用域终止时被释放。一旦发生未定义的行为,根据定义,结果是未定义的。 –

2

您的代码无效。你的'重新分配'不会做任何事情 - 你正在创建另一个影响名称的数组。与此同时,您覆盖了不属于您的内存(例如,p_values [9]是存储大小变量的地方)。继续下去,并且变得更加清晰:

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) 
+0

@Varshachik ...我现在明白了......谢谢! –

+0

新创建的数组没有做任何事情,并在括号剩下后被破坏 –

3

事实上

的问题
int size = 3; 
int p_values[size]; 

是无效的C++。这个特性(可变长度数组)是在1999年的标准中引入C语言的,并没有使用任何C++标准,或者建议添加它。一些C++编译器(以及一些C编译器早于1999 C标准)支持该功能,作为非标准扩展。

即使我们假定支持C的VLAS一个编译器,这

int size = 3; 
int p_values[size]; 

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

不调整p_values。它暂时在嵌套范围内(即在{}中)在范围外不再存在的情况下创建另一个数组。

+0

是的,我现在明白了......现在......非常感谢您的答案! –