Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.78/9: Рейтинг темы: голосов - 9, средняя оценка - 4.78
PlayaRC
5 / 5 / 1
Регистрация: 10.03.2012
Сообщений: 121
#1

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

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

Почему, если я выделяю память для одного 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
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
07.06.2014, 19:43
Ответы с готовыми решениями:

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

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

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

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

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

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

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

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

подробнее, пожалуйста, не могу понять разницу! заранее спасибо
0
Jupiter
Каратель
Эксперт С++
6568 / 3989 / 400
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
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
ValeryS
Модератор
7163 / 5430 / 674
Регистрация: 14.02.2011
Сообщений: 18,334
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
PlayaRC
5 / 5 / 1
Регистрация: 10.03.2012
Сообщений: 121
07.06.2014, 22:30  [ТС] #12
да обе ошибки завязаны на запись в чужую память, но это разные ошибки
че то я и правда попутал) спасибо, теперь все понятно

Добавлено через 1 минуту
Цитата Сообщение от ValeryS Посмотреть сообщение
но все меняется когда выбираешь релиз, подушки уже нет и программа рухает
так вот почему у меня не получалось переполнить буфер, нужно релиз выбрать
0
ValeryS
Модератор
7163 / 5430 / 674
Регистрация: 14.02.2011
Сообщений: 18,334
07.06.2014, 22:32 #13
Цитата Сообщение от PlayaRC Посмотреть сообщение
так вот почему у меня не получалось переполнить буфер, нужно релиз выбрать
не, можешь и число переполнения больше
Цитата Сообщение от PlayaRC Посмотреть сообщение
а если записать больше (например 100),
чтобы подушку пересечь
1
Renji
2156 / 1515 / 461
Регистрация: 05.06.2014
Сообщений: 4,394
07.06.2014, 23:46 #14
То в итоге я могу записать в myArray 8 интов
Потому что на машинном уровне память выделяется только страницами по четыре килобайта. Проверка допустимости чтения/записи тоже делается для всей страницы, а не для каждого int в отдельности.
тогда в чем отличия экзепшенов "Перполнения буфера" и "Куча повреждена"?
Переполнение буфера происходит в стеке и затирает адрес возврата из текущей процедуры. Соответственно, return будет вести черт знает куда. Например, на вредоносный код. Повреждение кучи подобных веселых последствий иметь скорее всего не будет.
0
ValeryS
Модератор
7163 / 5430 / 674
Регистрация: 14.02.2011
Сообщений: 18,334
08.06.2014, 06:47 #15
Цитата Сообщение от Renji Посмотреть сообщение
Потому что на машинном уровне память выделяется только страницами по четыре килобайта. Проверка допустимости чтения/записи тоже делается для всей страницы, а не для каждого int в отдельности.
хорошо
значит 4 КБ это это тысяча int
Цитата Сообщение от PlayaRC Посмотреть сообщение
если записать больше (например 100), то они запишутся дальше в памяти, но программа завершиться с ошибкой " Куча была повреждена
почему?
тысяча больше чем сто

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

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

http://wm-help.net/books-online/book/59464/59464-6.html
0
Croessmah
++Ͻ
14359 / 8141 / 1532
Регистрация: 27.09.2012
Сообщений: 20,070
Записей в блоге: 3
Завершенные тесты: 1
08.06.2014, 08:38 #17
Цитата Сообщение от uglyPinokkio Посмотреть сообщение
а программист что в килограмме 1024 грамма.
еще скажите, что в банк ходит ругаться из-за того, что банкомат выдал купюры номиналом 2, 4, 8 рублей
0
uglyPinokkio
326 / 229 / 55
Регистрация: 30.05.2014
Сообщений: 682
08.06.2014, 08:46 #18
Цитата Сообщение от Croessmah Посмотреть сообщение
еще скажите, что в банк ходит ругаться из-за того, что банкомат выдал купюры номиналом 2, 4, 8 рублей
Ну бородатый анекдот же.
0
ValeryS
Модератор
7163 / 5430 / 674
Регистрация: 14.02.2011
Сообщений: 18,334
08.06.2014, 08:58 #19
Цитата Сообщение от uglyPinokkio Посмотреть сообщение
Страницами оперирует не malloc а менеджер памяти.
А зачем ты мне это рассказываешь?
расскажи это Renji, который на вопрос
Цитата Сообщение от PlayaRC
Как malloc выделяет память?
отвечает
Цитата Сообщение от Renji Посмотреть сообщение
на машинном уровне память выделяется только страницами по четыре килобайта. Проверка допустимости чтения/записи тоже делается для всей страницы, а не для каждого int в отдельности.
Цитата Сообщение от uglyPinokkio Посмотреть сообщение
Обычный человек считает, что килобайт это тысяча байт, а программист что в килограмме 1024 грамма.
Я человек а не машина, и мне удобней оперировать человеческой а не машинной математикой
но могу переписать
значит 4 КБ это это тысяча двадцать четыре int
так устроит
хотя опять засада получается
никто не гарантировал,что int 4 байта
0
Renji
2156 / 1515 / 461
Регистрация: 05.06.2014
Сообщений: 4,394
08.06.2014, 11:44 #20
расскажи это Renji, который на вопрос
Вопрос был "почему я могу записать в myArray 8 интов". Защита памяти от записи выполняется на уровне процессора. Процессор оперирует страницами по четыре кило. Чем там оперирует malloc не важно, о его существовании процессор ничего не знает.
0
08.06.2014, 11:44
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
08.06.2014, 11:44

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

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

Нужно ли под массив выделять память функциями malloc или new?
собственно вот программа по вводу размера массива, вводу массива, сортировки:...


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

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

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