-3

В cpp можно использовать объявление массива как typename array [size]; или typename * array = new typename [size]; Где массив имеет длину 'size', а элементы индексируются от '0' до 'size -1' Здесь мой вопрос: я могу получить доступ к элементам за пределами индекса> = size.Почему cpp позволяет получить доступ к памяти, которую я не выделил?

Так что я написал этот небольшой код, чтобы проверить его

#include <iostream> 
using namespace std; 

int main() 
{ 
    //int *c;     //for dynamic allocation 
    int n;      //length of the array c 
    cin>>n;      //getting the length 
    //c = new int[n];   //for dynamic allocation 
    int c[n];     //for static allocation 

    for(int i=0; i<n; i++)  //getting the elements 
     cin>>c[i]; 

    for(int i=0; i<n+10; i++) //showing the elements, I have add up 10 
     cout<<c[i]<<" ";   //with size to access the memory I haven't 
           //allocated for 
    return 0; 
} 

И результат, как этого

2 
1 2 
1 2 2686612 1970422009 7081064 4199040 2686592 0 1 1970387429 1971087432 2686700 

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

Я использую CodeBlocks IDE, имеющего TDM-GCC 4.8.1 компилятора на окнах 8.1

Спасибо заранее.

+0

Это не разрешено, но C++ не проверяет это автоматически, как некоторые другие языки. Преимуществом является, например. более быстрые программы, недостатком является то, что происходит, если программист делает ошибку. (Кстати, возможно, ваши текущие программы работают нормально, но это действительно ошибка и часто вызывает проблемы) – deviantfan

+0

'int c [n];' фактически выделяет память. Его расширение компилятора GCC. –

+0

Вы можете использовать такой инструмент, как valgrind, чтобы обнаружить такие проблемы. –

ответ

0

Компиляторы C++ не применяют это, так как для этого нет спецификации.

Когда вы обращаетесь к элементу массива, проверка границ не выполняется. c[i] просто переводится на c + i * sizeof(int) и все. Если эта область памяти не инициализируется, вы получите мусор, но вы можете получить другую полезную информацию, все зависит от того, что там есть.

Обратите внимание, что в зависимости от операционной системы и времени выполнения C++ вы можете получать разные результаты, например, в окне linux вы, вероятно, получите segmentation fault, и программа выйдет из строя.

+0

Фактически, доступ к памяти с конца допустимого распределения не будет в большинстве случаев приводить к сбою сегментации, поскольку это является следствием механизма принудительного исполнения в MMU/MPU, который работает при детализации страницы. Если выделение находится на допустимой странице, вам нужно будет выйти за пределы этой страницы, в ситуации, когда нет выделенной страницы по следующему адресу. Некорректная операция по-прежнему вероятна, так как неправильный доступ может перезаписать другие важные данные или быть перезаписан более поздним действительным доступом. Это отличается от доступа к нераспределенной странице, которая может быть повреждена аппаратным обеспечением. –

1

Это называется неопределенным поведением в стандарте C++.

Неопределенное поведение может означать любое одно из следующих действий:

  • Программа разбивает

  • Программа продолжает работать, но дает бессмысленные, результаты мусора

  • Программа продолжает запускать и автоматически копировать все содержимое вашего жесткого диска и размещать его на Facebook

  • Программа продолжает работать, и автоматически выписывает вам Издатели Инфоресурса Sweepstakes

  • Программа продолжает работать, но ваш компьютер воспламеняется и взрывается

  • Программа продолжает работать, и делает ваш компьютер само- известно, что автоматически связи и сети с другими самоосознающими сетями, образуя Скайнет, и уничтожающее человеческого рода

Вывод: не работают и доступ к элементам за конец ваших массивов.

+0

Еще один бесполезный неопределенный ответ на поведение, когда плакат просто делает вещи для удовольствия, не отвечая на вопрос, потому что «что-то может случиться», когда задействовано неопределенное поведение. – asimes

+1

Какая часть моего ответа была неточны? –

+1

Я не сказал, что это было неточно, я сказал, что это бесполезно – asimes