Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.60/5: Рейтинг темы: голосов - 5, средняя оценка - 4.60
0 / 0 / 0
Регистрация: 07.09.2014
Сообщений: 4

Почему это компилируется, ведь под второй массив по идее не выделено в куче памяти

11.09.2014, 23:38. Показов 1096. Ответов 15
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
К сожалению на момент создания темы исходника не было под рукой...В общем что значит вот такой способ инициации двухмерного массива:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
int A,B
cin>>A;cin>>B;
double** BlockField_memory= new double* [A];
for(int a=0;a<A;a++)
    {
 BlockField_memory[a]=new double[B];
    }
double BlockField[A][B];
*действия с BlockField[A][B]*
for(int a=0;a<A;a++)
    {
delete BlockField_memory[A];
    }
delete[] BlockField_memory;
Странно, не так ли? А теперь внимание- это компилируется и работает! С такой матрицей можно что угодно делать, сам проверял. Наткнулся на такое в чужом коде, стало любопытно. Зачем переобъявлять массив еще раз? Почему это компилируется, ведь под второй массив по идее не выделено в куче памяти Оо?
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
11.09.2014, 23:38
Ответы с готовыми решениями:

По идее не должно компилироваться, но компилируется. Почему?
здравствуйте, подскажите, почему компилируется конструкция: BOOST_MPL_ASSERT((boost::mpl::equal&lt;boost::variant&lt;int, double&gt;, ...

В массив записывается больше, чем было выделено памяти
Я выделил 10 байт для хранения массива типа char, но я могу в него записать почему-то больше значений. Менял RAZM на 20 и даже на 2000 и...

Компилируется то, что по идее не должно
Недавно писал программмку и наткнулся на очень интересную вешь: #include &lt;iostream&gt; using namespace std; int main() { ...

15
 Аватар для IrineK
2023 / 1641 / 425
Регистрация: 23.02.2011
Сообщений: 6,002
Записей в блоге: 25
12.09.2014, 00:07
Цитата Сообщение от FulcrumPlus Посмотреть сообщение
Зачем переобъявлять массив еще раз?
Один называется
Цитата Сообщение от FulcrumPlus Посмотреть сообщение
BlockField_memory
второй
Цитата Сообщение от FulcrumPlus Посмотреть сообщение
BlockField
Где переобъявление?
0
 Аватар для contedevel
57 / 55 / 13
Регистрация: 07.10.2012
Сообщений: 606
12.09.2014, 00:17
Цитата Сообщение от FulcrumPlus Посмотреть сообщение
C++
1
double** BlockField_memory= new double* [A];
В общем не уловил фишки со вторым массивом (да и с первым тоже)
Но первый массив - это просто динамически созданный одномерный массив указателей, то есть каждый его элемент ссылается на динамический массив размерности B, хотя может ссылаться даже просто на переменную или массивы разных размерностей или иметь нулевой указатель
0
5500 / 4895 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
12.09.2014, 00:25
Цитата Сообщение от FulcrumPlus Посмотреть сообщение
А теперь внимание- это компилируется
Нет. В первой строке точка с запятой забыты. В студии вот эта строка не пройдёт (по стандарту, размерность, статически создаваемого массива, должна быть константной):
C++
1
double BlockField[A][B];
Цитата Сообщение от FulcrumPlus Посмотреть сообщение
и работает!
Нет, у меня виснет. Освождение памяти неверное, в 12 строке нужно:
C++
1
delete [] BlockField_memory[a];
0
 Аватар для contedevel
57 / 55 / 13
Регистрация: 07.10.2012
Сообщений: 606
12.09.2014, 00:26

Не по теме:

Блин, что-то сразу не въехал


Второй массив скорее всего на стадии компиляции в динамический преобразуется, сейчас попробую точно посмотреть, но это должно от компилятора зависеть, сам язык такого не должен позволять
0
Эксперт PHP
 Аватар для Kerry_Jr
3106 / 2591 / 1219
Регистрация: 14.05.2014
Сообщений: 7,236
Записей в блоге: 1
12.09.2014, 00:32
У меня MinGW 4.8.1, и такой код
C++
1
2
3
int a;
cin >> a;
int b[a];
спокойно компилируется без каких-либо проблем.
0
Модератор
Эксперт по электронике
8981 / 6748 / 921
Регистрация: 14.02.2011
Сообщений: 23,870
12.09.2014, 00:38
Цитата Сообщение от FulcrumPlus Посмотреть сообщение
Странно, не так ли?
а что странного?
нет такого понятия двумерный массив при динамике, есть массив указателей,можно с большой натяжкой назвать массив массивов
Цитата Сообщение от FulcrumPlus Посмотреть сообщение
C++
1
double** BlockField_memory= new double* [A];
выделяем массив указателей на тип double
Цитата Сообщение от FulcrumPlus Посмотреть сообщение
C++
1
2
3
4
for(int a=0;a<A;a++)
    {
 BlockField_memory[a]=new double[B];
    }
каждому указателю присваиваем значения выделенной памяти под одномерный массив double
и не факт что они будут лежать рядом это не статика
типа
C++
1
2
double a[2][2];
a[0][2]=5;// по факту запишем в a[1][1]=5
с динамикой такое не пройдет, как минимум исключение неправомерный доступ
про все остальное alsav22, сказал

Добавлено через 1 минуту
Цитата Сообщение от Kerry_Jr Посмотреть сообщение
У меня MinGW 4.8.1, и такой код
и что???
стандарт открой и посмотри
а то что GNUс ведет себя не по стандарту это всем давно известно
0
5500 / 4895 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
12.09.2014, 00:38
Цитата Сообщение от Kerry_Jr Посмотреть сообщение
спокойно компилируется без каких-либо проблем
Солтер Н.А., Клепер С.Дж. "С++ для профессионалов".
Миниатюры
Почему это компилируется, ведь под второй массив по идее не выделено в куче памяти  
0
 Аватар для contedevel
57 / 55 / 13
Регистрация: 07.10.2012
Сообщений: 606
12.09.2014, 00:50
Вот дизассемблированный код с исходным в перемешку, думаю, наглядно показывает, как компилятор преобразует код
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
6   {
0x4007dd    push   rbp
0x4007de    mov    rbp,rsp
0x4007e1    push   r15
0x4007e3    push   r14
0x4007e5    push   r13
0x4007e7    push   r12
0x4007e9    push   rbx
0x4007ea    sub    rsp,0x258
0x4007f1    mov    rax,rsp
0x4007f4    mov    rbx,rax
7       int A;
8       cin >> A;
0x4007f7    lea    rax,[rbp-0x260]
0x4007fe    mov    rsi,rax
0x400801    mov    edi,0x601060
0x400806    call   0x4006e0 <std::istream::operator>>(int&)@plt>
9       int b[A];
0x40080b    mov    eax,DWORD PTR [rbp-0x260]
0x400811    cdqe
0x400813    sub    rax,0x1
0x400817    mov    QWORD PTR [rbp-0x270],rax
0x40081e    mov    rdx,rax
0x400821    add    rdx,0x1
0x400825    mov    r14,rdx
0x400828    mov    r15d,0x0
0x40082e    mov    rdx,rax
0x400831    add    rdx,0x1
0x400835    mov    r12,rdx
0x400838    mov    r13d,0x0
0x40083e    add    rax,0x1
0x400842    shl    rax,0x2
0x400846    lea    rdx,[rax+0x3]
0x40084a    mov    eax,0x10
0x40084f    sub    rax,0x1
0x400853    add    rax,rdx
0x400856    mov    ecx,0x10
0x40085b    mov    edx,0x0
0x400860    div    rcx
0x400863    imul   rax,rax,0x10
0x400867    sub    rsp,rax
0x40086a    mov    rax,rsp
0x40086d    add    rax,0x3
0x400871    shr    rax,0x2
0x400875    shl    rax,0x2
0x400879    mov    QWORD PTR [rbp-0x268],rax
10      int a[140];
11      for(int i = 0; i < A; i++)
0x400880    mov    DWORD PTR [rbp-0x27c],0x0
0x40088a    jmp    0x4008ac <main()+207>
0x4008a5    add    DWORD PTR [rbp-0x27c],0x1
0x4008ac    mov    eax,DWORD PTR [rbp-0x260]
0x4008b2    cmp    DWORD PTR [rbp-0x27c],eax
0x4008b8    jl     0x40088c <main()+175>
12          b[i] = i;
0x40088c    mov    rax,QWORD PTR [rbp-0x268]
0x400893    mov    edx,DWORD PTR [rbp-0x27c]
0x400899    movsxd rdx,edx
0x40089c    mov    ecx,DWORD PTR [rbp-0x27c]
0x4008a2    mov    DWORD PTR [rax+rdx*4],ecx
13      for(int i = 0; i < 140; i++)
0x4008ba    mov    DWORD PTR [rbp-0x278],0x0
0x4008c4    jmp    0x4008cd <main()+240>
0x4008c6    add    DWORD PTR [rbp-0x278],0x1
0x4008cd    cmp    DWORD PTR [rbp-0x278],0x8b
0x4008d7    jle    0x4008c6 <main()+233>
14          a[i];
15      for(int i = 0; i < A; i++)
0x4008d9    mov    DWORD PTR [rbp-0x274],0x0
0x4008e3    jmp    0x40090b <main()+302>
0x400904    add    DWORD PTR [rbp-0x274],0x1
0x40090b    mov    eax,DWORD PTR [rbp-0x260]
0x400911    cmp    DWORD PTR [rbp-0x274],eax
0x400917    jl     0x4008e5 <main()+264>
16          cout << b[i];
0x4008e5    mov    rax,QWORD PTR [rbp-0x268]
0x4008ec    mov    edx,DWORD PTR [rbp-0x274]
0x4008f2    movsxd rdx,edx
0x4008f5    mov    eax,DWORD PTR [rax+rdx*4]
0x4008f8    mov    esi,eax
0x4008fa    mov    edi,0x601180
0x4008ff    call   0x400680 <std::ostream::operator<<(int)@plt>
17      return 0;
0x400919    mov    eax,0x0
0x40091e    mov    rsp,rbx
18  }
0x400921    lea    rsp,[rbp-0x28]
0x400925    pop    rbx
0x400926    pop    r12
0x400928    pop    r13
0x40092a    pop    r14
0x40092c    pop    r15
0x40092e    pop    rbp
0x40092f    ret
0
Форумчанин
Эксперт CЭксперт С++
 Аватар для MrGluck
8216 / 5047 / 1437
Регистрация: 29.11.2010
Сообщений: 13,453
12.09.2014, 00:53
Цитата Сообщение от Kerry_Jr Посмотреть сообщение
спокойно компилируется без каких-либо проблем.
Это называется VLA(variable length array), входят в стандарт С99, однако ни в одном из стандартов С++ не подтверждены. В gcc уже давно используется данная плюшка, но вот VS компиль до неё так и не дотянулся. Используйте динамические массивы заместо них.

Цитата Сообщение от ValeryS Посмотреть сообщение
а то что GNUс ведет себя не по стандарту это всем давно известно
ровно как и компиль vs

Добавлено через 1 минуту
Цитата Сообщение от FulcrumPlus Посмотреть сообщение
C++
1
2
3
4
for(int a=0;a<A;a++)
   {
delete BlockField_memory[A];
   }
C++
1
delete BlockField_memory[a];
0
5500 / 4895 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
12.09.2014, 01:17
Цитата Сообщение от MrGluck Посмотреть сообщение
delete BlockField_memory[a];
Тут разве память не под массивом освобождается?
0
835 / 643 / 101
Регистрация: 20.08.2013
Сообщений: 2,524
12.09.2014, 01:33
Цитата Сообщение от Kerry_Jr Посмотреть сообщение
спокойно компилируется без каких-либо проблем.
Интересно, а если напихать блоков, добавить переменных, что-нибудь похимичить и шмякнуть ещё goto, то тоже без проблем будет?)))

Добавлено через 1 минуту
Цитата Сообщение от FulcrumPlus Посмотреть сообщение
C++
1
delete BlockField_memory[A];
C++
1
delete[] BlockField_memory[A];
0
5500 / 4895 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
12.09.2014, 01:36
Цитата Сообщение от Qwertiy Посмотреть сообщение
C++
1
delete[] BlockField_memory[A];
Нет, выход за границу.
1
835 / 643 / 101
Регистрация: 20.08.2013
Сообщений: 2,524
12.09.2014, 01:48
Цитата Сообщение от alsav22 Посмотреть сообщение
Нет, выход за границу.
Блин.. Я невнимательный
Имел в виду, что надо скобочки delete'у поставить, а остальное скопипастил не проверяя. В общем, так:
C++
1
delete[] BlockField_memory[a];
0
5500 / 4895 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
12.09.2014, 02:01
Цитата Сообщение от Qwertiy Посмотреть сообщение
В общем, так:
4 пост.
1
Форумчанин
Эксперт CЭксперт С++
 Аватар для MrGluck
8216 / 5047 / 1437
Регистрация: 29.11.2010
Сообщений: 13,453
12.09.2014, 10:37
Цитата Сообщение от alsav22 Посмотреть сообщение
Тут разве память не под массивом освобождается?
А это вторая явная ошибка. Я указал лишь на взятие неверного индекса т.к. это первое что бросилось в глаза.
Спасибо за уточнение.

Добавлено через 1 минуту
Да и не заметил, что у вас уже пример готовый есть.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
12.09.2014, 10:37
Помогаю со студенческими работами здесь

Почему это компилируется?
Компилятор не видит, что одному и тому же параметризованному типу присваивают разные типы? public static void main(String...

Выделение памяти под массив в классе. Почему не могу правильно выделить?
Все привет! не могу понять почему в классе не получается выделить память из стека для массива. Есть класс: Надо чтоб конструктор класса...

Конструктор класса по умолчанию: код компилируется, хотя по идее не должен
#include &lt;iostream&gt; class A {}; int main() { A i; A j(i); return 0;

Нужно ли удалять указатель на символьный массив созданный в куче(динамически распределяемой памяти)
Подскажите, программа состоит из 2 функций (main и fun), программа меняет значение указателя на символьный массив созданный в динамически...

Можно ли так выделить память в куче под указатель на массив?
Здравствуйте Можно ли выделить память в куче под указатель на массив например так:? int (*c)=(int (*)) new int; или нужно как...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
16
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru