Почему один 2-й массив вызывает ошибку сегмента, а другой нет? - PullRequest
0 голосов
/ 20 октября 2019

Есть несколько способов определить массив 2-й.

И я обнаружил, что при определении массива с использованием приведенного ниже кода:

int arr[2][2];
cout << arr[3][3];

это не приводит к seg-fault. Это просто выводит какое-то фиктивное значение.

С другой стороны,

int** arr = new int*[2];
for(int i = 0; i < 2; i++) arr[i] = new int[2];
cout << arr[3][3];

это приводит к ошибке сегмента.

В чем разница между ними?

Ответы [ 3 ]

3 голосов
/ 20 октября 2019

Чтение неинициализированных значений: Неопределенное поведение . Ваша программа недействительна (оба варианта) и имеет , не означающее , когда вы делаете это, и любое поведение разрешено. Компилятору буквально разрешено делать что угодно . Вы не можете рассуждать о программе, содержащей UB, даже не пытайтесь.

1 голос
/ 20 октября 2019

Статические массивы расположены в стеке, поэтому они не могут быть сбоями, поскольку программа МОЖЕТ получить доступ к своему собственному стеку. Однако можно выйти из статического массива, если вы выйдете за пределы стека.

Динамический массив (указатель), с другой стороны, находится в куче. Таким образом, выходя за пределы диапазона, вы просите получить указатель вне выделенных областей памяти вашей программы, что приводит к segfault.

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

0 голосов
/ 20 октября 2019

У вас неопределенное поведение. Все может случиться. Нет смысла рассуждать, почему вы получаете эти результаты.

Тем не менее, вероятно, это происходит:

Первый - это непрерывный блок памяти (2 * 2 * sizeof (int)) в вашем стеке, где arr[3][3] означает чтение данных из 3 * 3 * sizeof (int) байтов после начала этого блока.

Другой - один блок памяти (2 * sizeof (int *))) в куче, содержащей два указателя, указывающие на два отдельных блока памяти в куче (каждый 2 * sizeof (int)), где arr[3][3] означает чтение данных из 3 * sizeof (int *) байтов после этого первого блока памятиинтерпретируйте все, что вы там найдете, как адрес памяти, а затем прочитайте данные из 3 * sizeof (int) байтов после этого адреса.

...