Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 11, средняя оценка - 4.64
taras atavin
3570 / 1753 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
#1

Теория по динамической памяти - C++

13.12.2012, 06:06. Просмотров 1414. Ответов 41
Метки нет (Все метки)

Предположим, применяется оператор new в форме для массива:
C++
1
p=new int [n];
. n ведь может быть и большим. Может n==1000000? Где запоминается, сколько выделено памяти и откуда система знает, сколько надо освободить памяти по
C++
1
delete [] p;
? Ведь там то я n не указываю. Может надо освободить сразу много страниц? Освобождаются все страницы, расположенные подряд? Эйси. А если я сначала выделили две страницы, а потом ещё три и все пять оказались подряд? А освобождаю сначала две? За счёт чего система заберёт только первую страницу, а не все пять? Или они не могут быть подряд?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
13.12.2012, 06:06
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Теория по динамической памяти (C++):

Освобождение динамической памяти в vs - C++
Вообщем попался я тут, и так, код: //#define _CRT_SECURE_NO_WARNINGS добавить в vs #include <iostream> #include <stdlib.h> ...

выделение динамической памяти - C++
помогите пожалуйста , нужно написать функцию для ввода новой матрицы, не получается выделить под него память. класс: mymatrix ::...

Удаление new из динамической памяти - C++
Здравствуйте, у меня есть следующее присвоение: sign->numb = new int; Мне нужно от него избавиться в конце программы, но delete...

Выделение динамической памяти - C++
Добрый вечер. Помогите разобраться пожалуйста! Суть такова: есть файл, в нем есть данные, мне надо их оттуда считать и вывести на...

Вопрос по динамической памяти - C++
мне надо создать масив содержащий структуры. У меня вот код какой: vec *fild;//vec это название структуры конструктор ...

Выделение динамической памяти C++ - C++
Всем доброго времени суток. Вот столкнулся с проблемой и пока что не приходит ничего интересного по поводу её решения. есть у меня метод,...

41
Vourhey
Почетный модератор
6486 / 2260 / 123
Регистрация: 29.07.2006
Сообщений: 12,635
13.12.2012, 06:16 #2
Цитата Сообщение от taras atavin Посмотреть сообщение
Где запоминается, сколько выделено памяти
Например, пишется в область перед выделенным буфером.
0
taras atavin
3570 / 1753 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
13.12.2012, 08:44  [ТС] #3
То есть дополнительный size_t перед самим блоком? А как оно в винде на самом деле? И может ли к этой инфе достучаться прилада? Чтоб не дублировать её каунтом.

Добавлено через 1 час 4 минуты
Такой:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
int main()
{
 int    *p;
 size_t *s;
 int     i;
 int     start;
 std::cin>>start;
 for (i=1; i<=16; ++i)
 {
  p=new int [i*start];
  s=(size_t*)p;
  std::cout<<i<<", "<<i*start<<", "<<(*s-1)<<std::endl;
  delete [] p;
 }
 return 0;
}
тест показал, что там мусор.
0
aLarman
642 / 563 / 89
Регистрация: 13.12.2012
Сообщений: 2,109
13.12.2012, 09:55 #4
Цитата Сообщение от taras atavin Посмотреть сообщение
То есть дополнительный size_t перед самим блоком?
нет не там) читай http://www.cplusplus.com/reference/new/operator%20new[]/

Добавлено через 57 секунд
и это http://www.cplusplus.com/reference/new/operator%20delete[]/
0
taras atavin
3570 / 1753 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
13.12.2012, 10:59  [ТС] #5
Ещё: откуда new знает, можно ли выделить память в уже имеющейся странице, или уже нет?

Добавлено через 6 минут
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 <iostream>
int main()
{
 int *p[16];
 int  i;
 for (i=15; i>=0; --i)
 {
  p[i]=new int [16];
 }
 for (i=15; i>=0; --i)
 {
  std::cout<<i<<", "<<p[i];
  if (i>0)
  {
   std::cout<<", "<<(p[i]-p[i-1]);
  }
  std::cout<<std::endl;
 }
 for (i=15; i>=0; --i)
 {
  delete [] p;
 }
 return 0;
}
показывает, что иногда несколько раз выделяется память в одной и той же странице.

Добавлено через 17 минут
Цитата Сообщение от aLarman Посмотреть сообщение
нет не там) читай http://www.cplusplus.com/reference/new/operator%20new[]/
Добавлено через 57 секунд
и это http://www.cplusplus.com/reference/n...rator%20delete[]/
Как применять я знаю и так. А откуда известно, использована ли страница полностью, или нет и какие именно байты из неё можно выдать?
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 <iostream>
int main()
{
 int *p[16];
 int  i;
 for (i=15; i>=0; --i)
 {
  p[i]=new int [2];
 }
 for (i=15; i>=0; --i)
 {
  std::cout<<i<<", "<<p[i];
  if (i>0)
  {
   std::cout<<", "<<(p[i-1]-p[i])<<", "<<((p[i-1]-p[i])/sizeof(int));
  }
  std::cout<<std::endl;
 }
 for (i=15; i>=0; --i)
 {
  delete [] p;
 }
 return 0;
}
показывает, что могут быть выданы много адресов в одной странице. Кстати, почему-то шаг равен размеру одного инта. Откуда делит знает, можно ли у прилады забрать всю страницу?

Добавлено через 30 минут
Сам прогнал, не учёл, что вычитание даёт разницу в сайзофах, а не байтах.
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
28
29
30
#include <iostream>
int main()
{
 int *p[16];
 char *v1;
 char *v2;
 int  i;
 size_t t;
 for (i=15; i>=0; --i)
 {
  p[i]=new int [2];
 }
 for (i=15; i>=0; --i)
 {
  std::cout<<i<<", "<<p[i];
  if (i>0)
  {
   v1=(char *)p[i];
   v2=(char *)p[i-1];
   t=v2-v1;
   std::cout<<", "<<t<<", "<<(t/sizeof(int));
  }
  std::cout<<std::endl;
 }
 for (i=15; i>=0; --i)
 {
  delete [] p;
 }
 return 0;
}
Выделяет почти вплотную.
0
aLarman
642 / 563 / 89
Регистрация: 13.12.2012
Сообщений: 2,109
13.12.2012, 16:15 #6
Цитата Сообщение от taras atavin Посмотреть сообщение
for (i=15; i>=0; --i)
{
delete [] p;
}
кажется
C++ (Qt)
1
2
3
4
for (i=15; i>=0; --i)
 {
 delete [] p[i];
 }
ну это не суть
в твоем примере тут
C++ (Qt)
1
2
3
4
for (i=15; i>=0; --i)
 {
  p[i]=new int [2];
 }
оператор new выделяет память на 2 элемента типа int и возвращает указатель на начало этого массива, который в итоге записывается в p[i].То, что он должен выделять эти 16 массивов по 2 элемента не означает, что они будут находиться в памяти линейно- где выделилось на то и вернул указатель)
0
Vourhey
Почетный модератор
6486 / 2260 / 123
Регистрация: 29.07.2006
Сообщений: 12,635
13.12.2012, 17:03 #7
Цитата Сообщение от taras atavin Посмотреть сообщение
То есть дополнительный size_t перед самим блоком?
Да.
Цитата Сообщение от taras atavin Посмотреть сообщение
тест показал, что там мусор.
Не смотрел, какой у тебя тест, у меня все нормально:
$ cat ./main.cpp
#include <iostream>

int main()
{
char *a = new char[16];
std::cout<<(long long)*(a-8)<<std::endl;
}
$ g++ main.cpp
$ ./a.out
33
33 - потому что new выделяет память дополнительно к тому, что была запрошена.
Если увеличить кол-во памяти, которое нужно, например, до 64:
$ cat main.cpp
#include <iostream>

int main()
{
char *a = new char[64];
std::cout<<(long long)*(a-8)<<std::endl;
}
$ g++ main.cpp
$ ./a.out
81
Видно, что разница опять на 17.

Добавлено через 15 минут
Цитата Сообщение от Vourhey Посмотреть сообщение
Цитата Сообщение от taras atavin Посмотреть сообщение
То есть дополнительный size_t перед самим блоком?
Да.
Точнее, почти
2
aLarman
642 / 563 / 89
Регистрация: 13.12.2012
Сообщений: 2,109
13.12.2012, 17:14 #8
Цитата Сообщение от Vourhey Посмотреть сообщение
Не смотрел, какой у тебя тест, у меня все нормально:
$ cat ./main.cpp
#include <iostream>
int main()
{
char *a = new char[16];
std::cout<<(long long)*(a-8)<<std::endl;
}
$ g++ main.cpp
$ ./a.out
33
33 - потому что new выделяет память дополнительно к тому, что была запрошена.
сделал что то подобное
C++
1
2
3
4
5
int *pInt;
    pInt = new int[10];
    for(int i=0;i<10;i++)
        pInt[i]=i;
    cout<<*(pInt-1)<<endl;
при каждом запуске разные числа и я почему то не удивлен) например сейчас получил -33686019

Добавлено через 3 минуты
хотя нет оно не меняется, ибо является мусором и видимо его никто не переписывает, даже если я меняю размер исходного массива, число не меняется) так что не там хранится размер массива)

Добавлено через 3 минуты
Vourhey, а твой пример выдал -98 и так же не меняется с изменением размера массива)
0
Vourhey
Почетный модератор
6486 / 2260 / 123
Регистрация: 29.07.2006
Сообщений: 12,635
13.12.2012, 17:15 #9
Цитата Сообщение от aLarman Посмотреть сообщение
при каждом запуске разные числа и я почему то не удивлен)
Наверное, потому что ты невнимателен.

Добавлено через 38 секунд
Цитата Сообщение от aLarman Посмотреть сообщение
Vourhey, а твой пример выдал -98 и так же не меняется с изменением размера массива)
Ты почитай мое первое сообщение, чтобы глупых вопросов больше не возникало.
0
aLarman
642 / 563 / 89
Регистрация: 13.12.2012
Сообщений: 2,109
13.12.2012, 17:20 #10
твой пример работает не так как ты пишешь, у меня в частности, проверь сам, что бы не было глупых ответов)
0
Vourhey
Почетный модератор
6486 / 2260 / 123
Регистрация: 29.07.2006
Сообщений: 12,635
13.12.2012, 17:44 #11
Цитата Сообщение от aLarman Посмотреть сообщение
твой пример работает не так как ты пишешь, у меня в частности, проверь сам, что бы не было глупых ответов)
Тяжелый случай...
Цитата Сообщение от Vourhey Посмотреть сообщение
Например, пишется в область перед выделенным буфером.
Слово "например" тебе о чем-то говорит? Тебе оно должно было сказать, что "это зависит от реализации" и один из вариантов - блок перед буфером. Это так же работает не только в g++ Linux, но и в VxWorks.
То, как это работает у тебя - это будет другое "например", поэтому ответь автору по-нормальному, а не пытайся доказать то, что заранее неправда, так как, вариантов несколько.

Добавлено через 17 минут
Цитата Сообщение от aLarman Посмотреть сообщение
int *pInt; pInt = new int[10]; for(int i=0;i<10;i++) pInt[i]=i; cout<<*(pInt-1)<<endl;
Если запускать его в студии, то я бы поменял вот так:
C++
1
2
3
4
5
    int *pInt;
    pInt = new int[10];
    for(int i=0;i<10;i++)
        pInt[i]=i;
    cout<<*(pInt-4)<<endl;
И вывод - 40. Что и есть 10 * размер int. Если поменяю на:
C++
1
pInt = new int[128];
То вывод - 512
0
taras atavin
3570 / 1753 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
13.12.2012, 17:49  [ТС] #12
Если я триллион раз выделю память и освобожу указатель, то по методе "каждый следующий выделяется впереди" уйдём за границу адресного пространства. По кругу нельзя, так удаляться и снова выделяться мог второй по порядку указатель, а первый существовать всегда. Если выделять только целыми страницами то другая пакость. Может у меня 67108864 динамичских массива по 32 чара? Перерасход адресного пространства в 32768, так как в странице можно разместить 1048576 байт. + уйдём за физическую память, та как страница виртуальной памяти занимает столько же и в физической. А если разделять терминальными страницами, то адресное пространство будет исчерпано в 2 раза быстрее физической памяти. Как ни крути, надо вести учёт байтов, а не страниц. Как это делается в винде?
0
Vourhey
Почетный модератор
6486 / 2260 / 123
Регистрация: 29.07.2006
Сообщений: 12,635
13.12.2012, 17:49 #13
Ну и так...чисто посмотреть на "мусор" в памяти, если брать винду:
Теория по динамической памяти
0
v.a.l.i.d
413 / 378 / 10
Регистрация: 21.09.2012
Сообщений: 913
13.12.2012, 17:50 #14
Vourhey, Напишите, пожалуйста, как найти количество элементов в дин. массиве float и double. Для int вот это работает
C++
1
cout << "Количество элементов в динамическом массиве: " << *(a - sizeof(a[0])) / sizeof(a[0]) << endl;
а вот для float и double почему то не получается
0
taras atavin
3570 / 1753 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
13.12.2012, 17:55  [ТС] #15
Цитата Сообщение от Vourhey Посмотреть сообщение
И вывод - 40. Что и есть 10 * размер int. Если поменяю на:
У меня при некоторых размерах наблюдается несколько лишних не выделенных интов между выделенными.

Добавлено через 3 минуты
Цитата Сообщение от v.a.l.i.d Посмотреть сообщение
(a - sizeof(a[0])) / sizeof(a[0]) << endl;
Это работает со статическими. И без разности.
0
13.12.2012, 17:55
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
13.12.2012, 17:55
Привет! Вот еще темы с ответами:

Удаление динамической памяти - C++
Всем здрасьте. Имеется вот такая структура. struct ModelType { DWORD FVF; IDirect3DVertexBuffer9* vertexBuffer; ...

Переменные в динамической памяти! - C++
подскажите как реализовать такое задание: Разместите в динамической памяти две переменные типа структура, содержащую информацию о...

Матрица в динамической памяти - C++
Здраствуйте,начал проходить динамическую память ,так немогу зделать 2-х мерный массив,помогите пожалуисто разобраться ,ии какие ошибки тут...

Освобождение динамической памяти - C++
После первого вызова функции(при повторном) пишет ошибку. В функции sort один из элементов массива становится недоступным для чтения. Если...


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

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru