Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.79/29: Рейтинг темы: голосов - 29, средняя оценка - 4.79
 Аватар для no_wearines
56 / 52 / 21
Регистрация: 01.01.2012
Сообщений: 347

В какой области памяти лежат объекты?

11.09.2017, 22:03. Показов 6490. Ответов 61
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здрст.

C++
1
2
3
4
5
6
7
8
struct H
{
    int a;
};
int main()
{
    H *p = new H;
}
объект по адресу p лежит в куче.
Вопрос: а где лежит объект-член 'a'? (в куче или в стеке)
и с помощью какого средства можно это проверить?
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
11.09.2017, 22:03
Ответы с готовыми решениями:

В какой области памяти хранится указатель (сама переменная, которая хранит адрес)?
Привет! В общем у меня возник небольшой вопрос :) Если мы объявляем указатель, выделяем ему память, то память выделяется в куче, а адрес...

Вопрпос про const: в какой области памяти они находятся, и где это объявлять ?
Приветствую. У меня вот такая задача - завести массив констант, причём он используется ТОЛЬКО одной функцией (не main), и поэтому,...

Считается ли хорошим тоном создавать объекты классов в области глобальных переменных
Считается ли хорошим тоном создавать объекты классов в области глобальных переменных? class FX { ........ ......... };

61
Модератор
Эксперт по электронике
8978 / 6744 / 921
Регистрация: 14.02.2011
Сообщений: 23,854
12.09.2017, 21:26
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от Captain Maxee Посмотреть сообщение
Так-то память для нее выделена на #1, но область ее видимости начинается только с #2,
не факт
в последнее время очень плотно сижу с микроконтроллерами
а там с памятью напряженка, а вот регистров очень многотак что локальные переменные очень часто запихиваются в регистр
причем может запихать в регистр который до этого использовала другая переменная
вполне возможен вариант когда область видимости равна "выделению памяти"
2
Неэпический
 Аватар для Croessmah
18144 / 10728 / 2066
Регистрация: 27.09.2012
Сообщений: 27,026
Записей в блоге: 1
12.09.2017, 21:44
hoggy, время жизни объекта у нас начинается когда?
C++
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
#include <iostream>
 
 
struct Test
{ 
    Test() {
        std::cout << "ctor" << std::endl;
    } 
};
 
 
void foo(bool x)
{
    static Test t1;
    if (x) {
        static Test t2;
    }
}
 
 
int main()
{
    std::cout << "1:\n";
    foo(false);
    std::cout << "2:\n";
    foo(true);
}
Цитата Сообщение от Notoriously Посмотреть сообщение
Допустим Эккель пишет, что память для всех переменных блока выделяется сразу при заходе в него.
Память для стека выделяется при старте процесса/потока.
Затем всё выделение на стеке сводится к работе с регистрами.
Если компилятор может посчитать сколько необходимо
памяти и выделить её на стеке одним махом, то почему нет?
Если же компилятор не может этого посчитать?
Проще всего такое продемонстрировать на C,
либо на C++ с VLA от GCC:
C
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
#include <stdio.h>
#include <stdlib.h>
 
void foo(int x, int y)
{
    char str[1024];
    scanf("%s", str);
    printf("%s", str);
    if( rand() ) {
       char buffer[x + y];
       scanf("%s", buffer);
       printf("block1: %s", buffer);
    } else {
       char buffer[y - x];
       scanf("%s", buffer);
       printf("block2: %s", buffer);
    }
}
 
 
 
int main(void)
{
    foo(1024, 2048);
}
Смотрим код foo в asm (смотрел с -O3):
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
foo(int, int):
  push rbp
  xor eax, eax
  mov rbp, rsp
  push r13
  push r12
  push rbx
  mov ebx, esi
  lea rsi, [rbp-1056]
  mov r13d, edi
  mov edi, OFFSET FLAT:.LC0
  sub rsp, 1032 ;<--РАЗ ВЫДЕЛЕНИЕ
  call scanf
  lea rsi, [rbp-1056]
  mov edi, OFFSET FLAT:.LC0
  xor eax, eax
  mov r12, rsp
  call printf
  call rand
  test eax, eax
  jne .L6
  sub ebx, r13d
  mov edi, OFFSET FLAT:.LC0
  xor eax, eax
  movsx rbx, ebx
  add rbx, 15
  and rbx, -16
  sub rsp, rbx ;<--ДВА ВЫДЕЛЕНИЕ
  mov rsi, rsp
  call scanf
  mov rsi, rsp
  mov edi, OFFSET FLAT:.LC2
  xor eax, eax
  call printf
  mov rsp, r12
  lea rsp, [rbp-24]
  pop rbx
  pop r12
  pop r13
  pop rbp
  ret
.L6:
  add ebx, r13d
  mov edi, OFFSET FLAT:.LC0
  xor eax, eax
  movsx rbx, ebx
  add rbx, 15
  and rbx, -16
  sub rsp, rbx  ;<--ТРИ ВЫДЕЛЕНИЕ
  mov rsi, rsp
  call scanf
  mov rsi, rsp
  mov edi, OFFSET FLAT:.LC1
  xor eax, eax
  call printf
  mov rsp, r12
  lea rsp, [rbp-24]
  pop rbx
  pop r12
  pop r13
  pop rbp
  ret
В общем случае стандарт не описывает что и когда должно выделяться.
А возьмем такой код:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <stdio.h>
#include <stdlib.h>
 
void foo(int x)
{
    bool f = x;
    if(f) {
        char str[1024];
        scanf("%s", str);
        printf("%s", str);
    } else {
        char str[64];
        scanf("%s", str);
        printf("t: %s", str);
    }
}
 
 
int main()
{
    int x;
    scanf("%d", &x);
    foo(x);
}
Смотрим asm:
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
.LC0:
  .string "%s"
foo(int) [clone .part.0]:
  sub rsp, 1032
  mov edi, OFFSET FLAT:.LC0
  xor eax, eax
  mov rsi, rsp
  call scanf
  mov rsi, rsp
  mov edi, OFFSET FLAT:.LC0
  xor eax, eax
  call printf
  add rsp, 1032
  ret
.LC2:
  .string "t: %s"
foo(int):
  sub rsp, 72
  test edi, edi
  jne .L8
  mov rsi, rsp
  mov edi, OFFSET FLAT:.LC0
  xor eax, eax
  call scanf
  mov rsi, rsp
  mov edi, OFFSET FLAT:.LC2
  xor eax, eax
  call printf
  add rsp, 72
  ret
.L8:
  call foo(int) [clone .part.0]
  add rsp, 72
  ret
.LC4:
  .string "%d"
main:
  sub rsp, 24
  mov edi, OFFSET FLAT:.LC4
  xor eax, eax
  lea rsi, [rsp+12]
  call scanf
  mov edi, DWORD PTR [rsp+12]
  call foo(int)
  xor eax, eax
  add rsp, 24
  ret
Как видим, у нас теперь вообще две "функции" foo.
GCC вообще разбил функцию на две и построил подобный код:
C++
1
2
3
4
5
6
7
8
9
10
11
12
void foo_part(int x)
{
   //ветка с массивом в 1024 элемента
}
 
void foo(int x)
{
   //выделение 72 байт
   if (x)
      foo_part(x);
   //ветка с массивом в 64 элемента
}
Так о каких там выделениях при заходе идет речь?
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
12.09.2017, 21:47
Цитата Сообщение от ValeryS Посмотреть сообщение
не факт
нет, факт.

Цитата Сообщение от ValeryS Посмотреть сообщение
часто запихиваются в регистр
монопенисуальный фактор.
Цитата Сообщение от ValeryS Посмотреть сообщение
вполне возможен вариант когда область видимости равна "выделению памяти"
не принципиальный момент.

принципиально, что вся память под статические/автоматические объекты
резервируется на этапе компиляции.

на этапе исполнения происходит инициализация объектов.
память же под эти объекты выделяется на этапе запуска процесса.

Добавлено через 1 минуту
Цитата Сообщение от Croessmah Посмотреть сообщение
Так о каких там выделениях при заходе идет речь?
не о женских разумеется.
а о тех, что случаются в момент запуска процесса,
я думаю.
0
Неэпический
 Аватар для Croessmah
18144 / 10728 / 2066
Регистрация: 27.09.2012
Сообщений: 27,026
Записей в блоге: 1
12.09.2017, 21:57
Цитата Сообщение от hoggy Посмотреть сообщение
а о тех, что случаются в момент запуска процесса
Это естественно. Только речь о автоматических объектах.
Двигаем указатель, получаем выделение на стеке.
Память же под стек, и, как следствие,
все автоматические объекты выделяется при старте процесса/потока.
Другое дело, когда будут двигаться эти самые "указатели".
C++
1
2
3
{
   int x;//это потенциальный sub/add (конечно же, компилятор всё посчитает. Ага.)
}
Те же самые статические объекты могут быть запиханы прямо в бинарник,
а могут просто просто превратиться число для bss.

Добавлено через 7 минут

Не по теме:

Цитата Сообщение от hoggy Посмотреть сообщение
не о женских разумеется
У кого что болит. Мне этот вариант даже в голову не пришел. :D

1
12.09.2017, 22:12

Не по теме:

Croessmah,
Да, я же упомянул, что в общем случае - это всё лежит на плечах компилятора.

0
12.09.2017, 22:17

Не по теме:

Notoriously, я и не спорю. Просто примерчик того, где не всё резервируется при заходе в блок. :)

0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
12.09.2017, 22:17
Цитата Сообщение от Croessmah Посмотреть сообщение
Другое дело, когда будут двигаться эти самые "указатели".
а это уже совсем другой вопрос.
к выделениям не женским отношения не имеющий.
0
Неэпический
 Аватар для Croessmah
18144 / 10728 / 2066
Регистрация: 27.09.2012
Сообщений: 27,026
Записей в блоге: 1
12.09.2017, 22:20
hoggy, наверное, фраза
"резервирование места на стеке под переменные"
подходит лучше, чем
"выделение места на стеке под переменные".
1
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
12.09.2017, 22:30
Цитата Сообщение от Croessmah Посмотреть сообщение
"резервирование места на стеке под переменные"
ни под какие "места для переменных" ничего специально не резервируется.

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

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

то есть, можно сказать,
что компилятор резервирует память под все объекты фрейма функции.
но он резервирует стековую память,
выделением которой он строго говоря не занимается.
1
Неэпический
 Аватар для Croessmah
18144 / 10728 / 2066
Регистрация: 27.09.2012
Сообщений: 27,026
Записей в блоге: 1
12.09.2017, 22:56
Цитата Сообщение от hoggy Посмотреть сообщение
ничего специально не резервируется
Цитата Сообщение от hoggy Посмотреть сообщение
то есть, можно сказать,
что компилятор резервирует память
Цитата Сообщение от hoggy Посмотреть сообщение
но он резервирует стековую память
Ы-ы-ы. О чем писали все газеты.
Что, тоже не удалось подобрать более подходящего термина?
Цитата Сообщение от hoggy Посмотреть сообщение
под все объекты фрейма функции.
В коде выше видим, что это не всегда так.
Резервирование может происходить "по месту".
1
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
12.09.2017, 23:19
Цитата Сообщение от Croessmah Посмотреть сообщение
О чем писали все газеты.
газета началась с вопроса: когда создаются объекты.
на этапе загрузки процесса создаются объекты.
объект - кусок памяти(ц)Страуструп.

Цитата Сообщение от Croessmah Посмотреть сообщение
Что, тоже не удалось подобрать более подходящего термина?
не над вырывать из контекста:
Цитата Сообщение от hoggy Посмотреть сообщение
что компилятор резервирует память под все объекты фрейма функции.
но он резервирует стековую память,
выделением которой он строго говоря не занимается.
компилятор на этапе компиляции колбасит стек на фреймы,
так, что бы размера фрейма гарантированно хватило под все его объекты.
а уж хватит ли самого стека...
Кликните здесь для просмотра всего текста
https://youtu.be/uXrKiuG-ybI



Цитата Сообщение от Croessmah Посмотреть сообщение
В коде выше видим, что это не всегда так.
в коде выше мы видим простейшую логику здравого смысла:
есть два объекта: 1 кг и 100 кг.
но жить одновременно они не могут.
следовательно, нет ни одной причины выделять под фрейм 101кг.
100кг хватит на все.
1
Неэпический
 Аватар для Croessmah
18144 / 10728 / 2066
Регистрация: 27.09.2012
Сообщений: 27,026
Записей в блоге: 1
12.09.2017, 23:38
Цитата Сообщение от hoggy Посмотреть сообщение
объект - кусок памяти(ц)Страуструп.
An object is a region of storage. (c) ISO/IEC 14882
Цитата Сообщение от hoggy Посмотреть сообщение
в коде выше
И код выше (первом) совершенно не об этом.
Цитата Сообщение от hoggy Посмотреть сообщение
следовательно, нет ни одной причины выделять под фрейм 101кг.
100кг хватит на все.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
 
void foo()
{
    //gcc 4.0.0 резервирует место под оба массива, несмотря на 
    if (rand()) {//взаимоисключающие ветки
        char a2[1512];
        memset(a2, 0, sizeof(a2));
    } else {
        char a2[1512];
        memset(a2, 0, sizeof(a2));
    }
}
 
int main()
{
    foo();
}
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
12.09.2017, 23:44
Цитата Сообщение от Croessmah Посмотреть сообщение
An object is a region of storage.
И?

Цитата Сообщение от Croessmah Посмотреть сообщение
Вот сюрприз
Он строго говоря и не обязан умничать.

Так то я бы не удивился,
если бы он догадался подсократить майн до
C++
1
int main() { return 0; }
а там и до всего процесса недалеко.
0
"C with Classes"
2022 / 1404 / 523
Регистрация: 16.08.2014
Сообщений: 5,885
Записей в блоге: 1
13.09.2017, 07:45
В самой куче данные могут храниться на стеке?
0
Велосипедист...
 Аватар для Mournful Max
353 / 220 / 73
Регистрация: 15.12.2015
Сообщений: 785
13.09.2017, 11:25
_stanislav, задам встречный вопрос, который должен стать ответом на Ваш вопрос: в левом кармане может быть правый карман?

Добавлено через 12 минут
Странный однако вопрос. Помнится, Вы писали неплохой код, посмотрев на него и на Ваш код, чувствуется какой-то подвох.
Или код писали не Вы?
0
Неэпический
 Аватар для Croessmah
18144 / 10728 / 2066
Регистрация: 27.09.2012
Сообщений: 27,026
Записей в блоге: 1
13.09.2017, 11:55
Цитата Сообщение от Captain Maxee Посмотреть сообщение
в левом кармане может быть правый карман?
Может.
0
Велосипедист...
 Аватар для Mournful Max
353 / 220 / 73
Регистрация: 15.12.2015
Сообщений: 785
13.09.2017, 13:13

Не по теме:

Croessmah, =-O
Это как? Искусственный стек? Это известный прием? Для чего такое может понадобиться?
( Если долго писать, то дайте направление, где искать )



Добавлено через 2 минуты

Не по теме:

Цитата Сообщение от Captain Maxee Посмотреть сообщение
Вы писали неплохой код, посмотрев на него и на Ваш код
Вы писали неплохой код, посмотрев на него и на Ваш вопрос

0
Неэпический
 Аватар для Croessmah
18144 / 10728 / 2066
Регистрация: 27.09.2012
Сообщений: 27,026
Записей в блоге: 1
13.09.2017, 13:13
Цитата Сообщение от Captain Maxee Посмотреть сообщение
Это известный прием?
Достаточно известный.
Цитата Сообщение от Captain Maxee Посмотреть сообщение
Это как?
Дырки в карманах в подкладку,
положил что-то в правый карман,
вытащил потом из левого.
Цитата Сообщение от Captain Maxee Посмотреть сообщение
Для чего такое может понадобиться?
Места больше, хотя использовать неудобно.
Цитата Сообщение от Captain Maxee Посмотреть сообщение
Искусственный стек?
Причем здесь стек? Мы о карманах же.
0
Велосипедист...
 Аватар для Mournful Max
353 / 220 / 73
Регистрация: 15.12.2015
Сообщений: 785
13.09.2017, 13:16
Цитата Сообщение от Croessmah Посмотреть сообщение
Причем здесь стек? Мы о карманах же.

Я думал, Вы это косвенно про "стек в куче" сказали))
Так уж и быть, сравнение с карманами вышло не очень.
0
"C with Classes"
2022 / 1404 / 523
Регистрация: 16.08.2014
Сообщений: 5,885
Записей в блоге: 1
13.09.2017, 19:58
Цитата Сообщение от Captain Maxee Посмотреть сообщение
задам встречный вопрос, который должен стать ответом на Ваш вопрос: в левом кармане может быть правый карман?
я имел ввиду, как реализовано хранение данных в самой куче.
Цитата Сообщение от Captain Maxee Посмотреть сообщение
Или код писали не Вы?
код писал я, причем быстро в лоб, особо не задумываясь, поэтому считаю годным только для примера.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
13.09.2017, 19:58
Помогаю со студенческими работами здесь

Перераспределение памяти с new под объекты
есть класс #include &lt;iostream&gt; #include &lt;string&gt; using namespace std; class tel_book { private: char *FIO; int count...

Объекты классов в динамической памяти
Я создаю объект класса в динамической памяти ( например map *obj = new map; ) Вопрос: как сделать трехмерый(или хотя бы двумерный) массив...

Выделение памяти под объекты классов
Здравствуйте, начал недавно осваивать классы и вот у меня в голове все крутится один вопрос. Каким образом происходит выделение памяти...

Динамическое выделение памяти под объекты
Создать класс с именем TRAIN, содержащий следующие закрытые поля: • название пункта назначения; • номер поезда; Написать...

Создать указатели и ссылки на объекты в памяти
Помогите, кто может Создайте в свободной памяти три объекта различных типов (Cat, Worker, Pencil…). Замените указатели ссылками и...


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

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Новые блоги и статьи
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка. Рецензия / Мнение/ Перевод https:/ / **********/ gallery/ thinkpad-x220-tablet-porn-gzoEAjs . . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru