2016-11-19 2 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. Почему я сказал в университете (а также в нескольких книгах), что в программе на С ++ увеличение использования памяти во время выполнения возможно только с помощью указателей? 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

Справедливости ради, это не программа на С ++. VLA не являются частью C++. – krzaq

+0

Указатели предназначены для указания на вещи. Как распределяются вещи - это другое дело. – juanchopanza

+0

Что такое VLA, если я могу спросить? –

ответ

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

Nope. Это не увеличивает размер существующего массива p_values, объявленного в начале функции. Это объявляет другой массив с именем p_values, во внутренней области ...

... и поскольку внутренний объем немедленно заканчивается здесь, это не имеет никакого эффекта. Цикл продолжается и заканчивается с конца исходного массива p_values, что приводит к неопределенному поведению и повреждению памяти.

Тем не менее, программа динамически увеличивает размер массива во время выполнения.

Нет, это не так. Размер существующего массива не был динамически увеличен. Другой большой массив переменной длины был объявлен во внутренней области и сразу же уничтожен. Исходный массив остался прежним, и это привело к неопределенному поведению.

Просто продолжайте вводить больше значений в массив, и в какой-то момент вы закончите разбивку адреса возврата в стеке, в результате чего получится segfault, когда возвращается main() (при условии, что ваш компилятор динамически реализует массивы переменной длины, размер фрейма стека текущей функции).

+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

@ Варшачик ... Я понимаю сейчас ... спасибо! –

+0

вновь созданный массив ничего не делает и уничтожается после того, как скобки оставлены –

3

В самом деле

int size = 3; 
int p_values[size]; 

не действует C++. Эта функция (массивы переменной длины) была введена на C со стандартом 1999 года и не является ни в одном стандарте C++, или предлагается добавить ее. Некоторые компиляторы C++ (и некоторые компиляторы C, предшествующие стандарту 1999 C) поддерживают эту функцию в качестве нестандартного расширения.

Даже если мы предположим, компилятор, который поддерживает Влас Ĉ, это

int size = 3; 
int p_values[size]; 

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

не изменяет размер p_values. Он временно создает другой массив во вложенной области (то есть в {}), который больше не существует вне области видимости.

+0

да, я понял, что сейчас ... большое спасибо за ваши ответы! –

Смежные вопросы