Форум программистов, компьютерный форум CyberForum.ru

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

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 9, средняя оценка - 4.89
PlayaRC
5 / 5 / 0
Регистрация: 10.03.2012
Сообщений: 121
#1

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

07.06.2014, 19:43. Просмотров 1441. Ответов 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)."
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
07.06.2014, 19:43
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Как malloc выделяет память? (C++):

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

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

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

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

Написать программу, которая вводит целое число n и выделяет память - C++
3. Написать программу, которая вводит целое число n и выделяет память для массива из n данных типа: char, int, double. Перед завершением...

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

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Jupiter
Каратель
Эксперт С++
6553 / 3973 / 226
Регистрация: 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)."
невезение
PlayaRC
5 / 5 / 0
Регистрация: 10.03.2012
Сообщений: 121
07.06.2014, 21:01  [ТС] #3
выход за пределы массива не контролируется
это понятно! я это специально и сделал! мне интересно почему память выделил 4 байта, а вместилось 32?
Pjeroo
Землянин
34 / 34 / 12
Регистрация: 15.01.2013
Сообщений: 313
07.06.2014, 21:11 #4
PlayaRC, под свою программу Вы выделили именно 4 байта, остальное это не размеченная область памяти, в ней хранится мусор и Вы можете её использовать, но не факт, что все будет гладко, можно набрести на область памяти другого процесса или типа того.
Jupiter
Каратель
Эксперт С++
6553 / 3973 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
07.06.2014, 21:14 #5
Цитата Сообщение от PlayaRC Посмотреть сообщение
мне интересно почему память выделил 4 байта, а вместилось 32?
malloc это абстракция для получения памяти и нечего лезть в детали реализации
kupnu4
26 / 26 / 9
Регистрация: 03.05.2013
Сообщений: 71
07.06.2014, 21:15 #6
так тебе ведь сказали, что тебе просто не повезло. вместилось 8 int'ов по стечению обстоятельств. могло вместится больше, а могло меньше. ты начал писать в чужую память начиная со второго элемента.
PlayaRC
5 / 5 / 0
Регистрация: 10.03.2012
Сообщений: 121
07.06.2014, 21:17  [ТС] #7
PlayaRC, под свою программу Вы выделили именно 4 байта, остальное это не размеченная область памяти, в ней хранится мусор и Вы можете её использовать, но не факт, что все будет гладко, можно набрести на область памяти другого процесса или типа того.
то есть 32 байта - это случайное число, могло быть и больше и меньше, так? это просто число байт, которые свободны от выделенного мне места до уже занятого участка памяти?

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

подробнее, пожалуйста, не могу понять разницу! заранее спасибо
Jupiter
Каратель
Эксперт С++
6553 / 3973 / 226
Регистрация: 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 взят для иллюстрации и он вовсе не обязательно бросит такой исключение так как ничего не знает о размере буферов

ValeryS
Модератор
6556 / 5022 / 464
Регистрация: 14.02.2011
Сообщений: 16,763
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 Посмотреть сообщение
Если и там, и там можно забрести в память выделенную другому процессу
память для процессов не пересекаемая
PlayaRC
5 / 5 / 0
Регистрация: 10.03.2012
Сообщений: 121
07.06.2014, 22:30  [ТС] #12
да обе ошибки завязаны на запись в чужую память, но это разные ошибки
че то я и правда попутал) спасибо, теперь все понятно

Добавлено через 1 минуту
Цитата Сообщение от ValeryS Посмотреть сообщение
но все меняется когда выбираешь релиз, подушки уже нет и программа рухает
так вот почему у меня не получалось переполнить буфер, нужно релиз выбрать
ValeryS
Модератор
6556 / 5022 / 464
Регистрация: 14.02.2011
Сообщений: 16,763
07.06.2014, 22:32 #13
Цитата Сообщение от PlayaRC Посмотреть сообщение
так вот почему у меня не получалось переполнить буфер, нужно релиз выбрать
не, можешь и число переполнения больше
Цитата Сообщение от PlayaRC Посмотреть сообщение
а если записать больше (например 100),
чтобы подушку пересечь
Renji
1904 / 1302 / 292
Регистрация: 05.06.2014
Сообщений: 3,734
07.06.2014, 23:46 #14
То в итоге я могу записать в myArray 8 интов
Потому что на машинном уровне память выделяется только страницами по четыре килобайта. Проверка допустимости чтения/записи тоже делается для всей страницы, а не для каждого int в отдельности.
тогда в чем отличия экзепшенов "Перполнения буфера" и "Куча повреждена"?
Переполнение буфера происходит в стеке и затирает адрес возврата из текущей процедуры. Соответственно, return будет вести черт знает куда. Например, на вредоносный код. Повреждение кучи подобных веселых последствий иметь скорее всего не будет.
ValeryS
Модератор
6556 / 5022 / 464
Регистрация: 14.02.2011
Сообщений: 16,763
08.06.2014, 06:47 #15
Цитата Сообщение от Renji Посмотреть сообщение
Потому что на машинном уровне память выделяется только страницами по четыре килобайта. Проверка допустимости чтения/записи тоже делается для всей страницы, а не для каждого int в отдельности.
хорошо
значит 4 КБ это это тысяча int
Цитата Сообщение от PlayaRC Посмотреть сообщение
если записать больше (например 100), то они запишутся дальше в памяти, но программа завершиться с ошибкой " Куча была повреждена
почему?
тысяча больше чем сто

Да и кто сказал что malloc оперирует страницами?
этак никакой памяти не напасешься
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
08.06.2014, 06:47
Привет! Вот еще темы с ответами:

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

Нужно ли под массив выделять память функциями malloc или new? - C++
собственно вот программа по вводу размера массива, вводу массива, сортировки: #include &lt;iostream&gt; #include &lt;windows.h&gt; using...

Выделить память под двумерный массив за один вызов функции malloc - C++
Выделить память под двумерный массив за один вызов функции malloc Если можно - с комментариями

Можно ли выделять память под объект класса с помощью функций calloc, malloc или realloc? - C++
Интересует данный вопрос. Можно ли и имеет ли вобще смысл например выделять память под объект класса с помощью функций calloc, malloc или...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
08.06.2014, 06:47
Ответ Создать тему
Опции темы

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