Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.92/26: Рейтинг темы: голосов - 26, средняя оценка - 4.92
5 / 5 / 1
Регистрация: 10.03.2012
Сообщений: 121
1

Как malloc выделяет память?

07.06.2014, 19:43. Показов 5245. Ответов 22
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Почему, если я выделяю память для одного int, вот так
C++
1
int *myArray = (int *)malloc(sizeof(int));
То в итоге я могу записать в myArray 8 интов
C++
1
2
        for (int i = 0; i < 8; i++)
            myArray[i] = i + 1;
и программа закончит работу вообще без ошибок, а если записать больше (например 100), то они запишутся дальше в памяти, но программа завершиться с ошибкой " Куча была повреждена (параметры: 0x77D2D338)."
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
07.06.2014, 19:43
Ответы с готовыми решениями:

Почему GlobalAlloc выделяет память в файле подкачки? И как "обрезать" ненужную память?
Стоит задача: выделяю, например, 40 байт, потом нужно эти же 40 байт обрезать до 20, не изменяя...

Realloc выделяет память для массива int и не выделяет память для массива double
Скажите пожалуйста, почему вот этот код работает: #include &lt;iostream&gt; #include &lt;windows.h&gt;...

Действительно ли new выделяет память в куче (heap)?
Чаще всего пишут что в куче . Ок . Куча процесса это вроде бы блок вполне конкретного размера . Я...

malloc и new (динамическая память)
Ребят, привет. ОЧчень интересует вопрос с динамической памятью . Как эта штука реализованна внутри...

22
Каратель
Эксперт С++
6609 / 4028 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
07.06.2014, 20:59 2
выход за пределы массива не контролируется

Цитата Сообщение от PlayaRC Посмотреть сообщение
То в итоге я могу записать в myArray 8 интов
for (int i = 0; i < 8; i++)
* myArray[i] = i + 1;
и программа закончит работу вообще без ошибок, а если записать больше (например 100), то они запишутся дальше в памяти, но программа завершиться с ошибкой " Куча была повреждена (параметры: 0x77D2D338)."
невезение
1
5 / 5 / 1
Регистрация: 10.03.2012
Сообщений: 121
07.06.2014, 21:01  [ТС] 3
выход за пределы массива не контролируется
это понятно! я это специально и сделал! мне интересно почему память выделил 4 байта, а вместилось 32?
0
Землянин
34 / 34 / 16
Регистрация: 15.01.2013
Сообщений: 312
07.06.2014, 21:11 4
PlayaRC, под свою программу Вы выделили именно 4 байта, остальное это не размеченная область памяти, в ней хранится мусор и Вы можете её использовать, но не факт, что все будет гладко, можно набрести на область памяти другого процесса или типа того.
1
Каратель
Эксперт С++
6609 / 4028 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
07.06.2014, 21:14 5
Цитата Сообщение от PlayaRC Посмотреть сообщение
мне интересно почему память выделил 4 байта, а вместилось 32?
malloc это абстракция для получения памяти и нечего лезть в детали реализации
0
26 / 26 / 15
Регистрация: 03.05.2013
Сообщений: 71
07.06.2014, 21:15 6
так тебе ведь сказали, что тебе просто не повезло. вместилось 8 int'ов по стечению обстоятельств. могло вместится больше, а могло меньше. ты начал писать в чужую память начиная со второго элемента.
1
5 / 5 / 1
Регистрация: 10.03.2012
Сообщений: 121
07.06.2014, 21:17  [ТС] 7
PlayaRC, под свою программу Вы выделили именно 4 байта, остальное это не размеченная область памяти, в ней хранится мусор и Вы можете её использовать, но не факт, что все будет гладко, можно набрести на область памяти другого процесса или типа того.
то есть 32 байта - это случайное число, могло быть и больше и меньше, так? это просто число байт, которые свободны от выделенного мне места до уже занятого участка памяти?

Добавлено через 2 минуты
тогда в чем отличия экзепшенов "Перполнения буфера" и "Куча повреждена"? Если и там, и там можно забрести в память выделенную другому процессу и записать туда что-то свое
0
Каратель
Эксперт С++
6609 / 4028 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
07.06.2014, 21:39 8
Цитата Сообщение от PlayaRC Посмотреть сообщение
тогда в чем отличия экзепшенов "Перполнения буфера" и "Куча повреждена"?
чтоб программист на этапе разработки знал в чем проблема
1
5 / 5 / 1
Регистрация: 10.03.2012
Сообщений: 121
07.06.2014, 21:43  [ТС] 9
чтоб программист на этапе разработки знал в чем проблема
то есть по сути это одно и тоже? что в первом, что во втором можно залезть в память выделенную другой программе?

подробнее, пожалуйста, не могу понять разницу! заранее спасибо
0
Каратель
Эксперт С++
6609 / 4028 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
07.06.2014, 21:51 10
Цитата Сообщение от PlayaRC Посмотреть сообщение
подробнее, пожалуйста, не могу понять разницу! заранее спасибо
что подробнее если тут все логично
C++
1
2
int* ptr;
*ptr = 42; //heap corruption
C++
1
2
char buf[]="abc", buf2[]="def";
strcat(buf, buf2);//buffer overflow
да обе ошибки завязаны на запись в чужую память, но это разные ошибки

Не по теме:

strcat взят для иллюстрации и он вовсе не обязательно бросит такой исключение так как ничего не знает о размере буферов

1
Модератор
Эксперт по электронике
8908 / 6677 / 918
Регистрация: 14.02.2011
Сообщений: 23,523
07.06.2014, 22:07 11
Цитата Сообщение от PlayaRC Посмотреть сообщение
То в итоге я могу записать в myArray 8 интов
вопрос какой компилятор?
и какой режим компилирования? отладочная или релизная?
например в отладочном(Debig) режиме VC при выделении памяти создает "подушку безопасности"
выделяет память не только под int но и до и после этой памяти
соответственно когда выходиш за границы массива ты не пишешь в чужую память, а пишешь в "подушку" программа не рухает но при закрытии программы, анализируется целостность подушки и выдает предупреждение " выход за границы"
посмотреть эту подушку можно например так
C++
1
2
3
4
5
int * a=(int *)malloc(sizeof(int));
*a=0x55555555;
char * c=(char*)a;
for(int i=-16;i<16;i++)
  printf(" %x",c[i]);
но все меняется когда выбираешь релиз, подушки уже нет и программа рухает

Добавлено через 1 минуту
Цитата Сообщение от PlayaRC Посмотреть сообщение
Если и там, и там можно забрести в память выделенную другому процессу
память для процессов не пересекаемая
2
5 / 5 / 1
Регистрация: 10.03.2012
Сообщений: 121
07.06.2014, 22:30  [ТС] 12
да обе ошибки завязаны на запись в чужую память, но это разные ошибки
че то я и правда попутал) спасибо, теперь все понятно

Добавлено через 1 минуту
Цитата Сообщение от ValeryS Посмотреть сообщение
но все меняется когда выбираешь релиз, подушки уже нет и программа рухает
так вот почему у меня не получалось переполнить буфер, нужно релиз выбрать
0
Модератор
Эксперт по электронике
8908 / 6677 / 918
Регистрация: 14.02.2011
Сообщений: 23,523
07.06.2014, 22:32 13
Цитата Сообщение от PlayaRC Посмотреть сообщение
так вот почему у меня не получалось переполнить буфер, нужно релиз выбрать
не, можешь и число переполнения больше
Цитата Сообщение от PlayaRC Посмотреть сообщение
а если записать больше (например 100),
чтобы подушку пересечь
1
2782 / 1935 / 570
Регистрация: 05.06.2014
Сообщений: 5,600
07.06.2014, 23:46 14
То в итоге я могу записать в myArray 8 интов
Потому что на машинном уровне память выделяется только страницами по четыре килобайта. Проверка допустимости чтения/записи тоже делается для всей страницы, а не для каждого int в отдельности.
тогда в чем отличия экзепшенов "Перполнения буфера" и "Куча повреждена"?
Переполнение буфера происходит в стеке и затирает адрес возврата из текущей процедуры. Соответственно, return будет вести черт знает куда. Например, на вредоносный код. Повреждение кучи подобных веселых последствий иметь скорее всего не будет.
0
Модератор
Эксперт по электронике
8908 / 6677 / 918
Регистрация: 14.02.2011
Сообщений: 23,523
08.06.2014, 06:47 15
Цитата Сообщение от Renji Посмотреть сообщение
Потому что на машинном уровне память выделяется только страницами по четыре килобайта. Проверка допустимости чтения/записи тоже делается для всей страницы, а не для каждого int в отдельности.
хорошо
значит 4 КБ это это тысяча int
Цитата Сообщение от PlayaRC Посмотреть сообщение
если записать больше (например 100), то они запишутся дальше в памяти, но программа завершиться с ошибкой " Куча была повреждена
почему?
тысяча больше чем сто

Да и кто сказал что malloc оперирует страницами?
этак никакой памяти не напасешься
0
327 / 230 / 55
Регистрация: 30.05.2014
Сообщений: 682
08.06.2014, 08:24 16
Цитата Сообщение от ValeryS Посмотреть сообщение
значит 4 КБ это это тысяча int
Чем отличается программист от обычного человека:
Обычный человек считает, что килобайт это тысяча байт, а программист что в килограмме 1024 грамма.

Цитата Сообщение от ValeryS Посмотреть сообщение
Да и кто сказал что malloc оперирует страницами?
Страницами оперирует не malloc а менеджер памяти.

http://wm-help.net/books-onlin... 464-6.html
0
Неэпический
17870 / 10635 / 2054
Регистрация: 27.09.2012
Сообщений: 26,737
Записей в блоге: 1
08.06.2014, 08:38 17
Цитата Сообщение от uglyPinokkio Посмотреть сообщение
а программист что в килограмме 1024 грамма.
еще скажите, что в банк ходит ругаться из-за того, что банкомат выдал купюры номиналом 2, 4, 8 рублей
0
327 / 230 / 55
Регистрация: 30.05.2014
Сообщений: 682
08.06.2014, 08:46 18
Цитата Сообщение от Croessmah Посмотреть сообщение
еще скажите, что в банк ходит ругаться из-за того, что банкомат выдал купюры номиналом 2, 4, 8 рублей
Ну бородатый анекдот же.
0
Модератор
Эксперт по электронике
8908 / 6677 / 918
Регистрация: 14.02.2011
Сообщений: 23,523
08.06.2014, 08:58 19
Цитата Сообщение от uglyPinokkio Посмотреть сообщение
Страницами оперирует не malloc а менеджер памяти.
А зачем ты мне это рассказываешь?
расскажи это Renji, который на вопрос
Цитата Сообщение от PlayaRC
Как malloc выделяет память?
отвечает
Цитата Сообщение от Renji Посмотреть сообщение
на машинном уровне память выделяется только страницами по четыре килобайта. Проверка допустимости чтения/записи тоже делается для всей страницы, а не для каждого int в отдельности.
Цитата Сообщение от uglyPinokkio Посмотреть сообщение
Обычный человек считает, что килобайт это тысяча байт, а программист что в килограмме 1024 грамма.
Я человек а не машина, и мне удобней оперировать человеческой а не машинной математикой
но могу переписать
значит 4 КБ это это тысяча двадцать четыре int
так устроит
хотя опять засада получается
никто не гарантировал,что int 4 байта
0
2782 / 1935 / 570
Регистрация: 05.06.2014
Сообщений: 5,600
08.06.2014, 11:44 20
расскажи это Renji, который на вопрос
Вопрос был "почему я могу записать в myArray 8 интов". Защита памяти от записи выполняется на уровне процессора. Процессор оперирует страницами по четыре кило. Чем там оперирует malloc не важно, о его существовании процессор ничего не знает.
0
08.06.2014, 11:44
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
08.06.2014, 11:44
Помогаю со студенческими работами здесь

Организовать функцию, которая выделяет память под строку
1) Организовать функцию, которая выделяет память под строку. Размер памяти передается через...

Написать программу, которая вводит целое число n и выделяет память
3. Написать программу, которая вводит целое число n и выделяет память для массива из n данных типа:...

И снова динамическая память, malloc и free в конструкторе и деструкторе
Короче есть, класс, который например хранит строку, я его храню в структуре, после я выдиляю...

Программа, которая считывает количество товаров и выделяет память для сохранения их цен
6. Напишите программу, которая считывает количество товаров и выделяет память для сохранения их...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru