Форум программистов, компьютерный форум, киберфорум
Наши страницы
C для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.67/6: Рейтинг темы: голосов - 6, средняя оценка - 4.67
DavidTs
3 / 3 / 8
Регистрация: 25.11.2015
Сообщений: 127
1

Почему malloc работает не так, как ожидается?

08.03.2016, 14:04. Просмотров 1176. Ответов 13
Метки нет (Все метки)

C
1
2
3
4
5
6
7
8
9
int main()
{
 
    int* p =malloc(sizeof(int));
    p[100]=5;
    printf("%s\n",strerror(errno));
    printf("%d",*(p+100));
    return 0;
}
0
Лучшие ответы (1)
QA
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
08.03.2016, 14:04
Ответы с готовыми решениями:

Код работает не так, как ожидается (найти и исправить ошибки)
#include <stdio.h> #include <conio.h> #include <string.h> char deletika(char a, long ot, long...

Почему так себя ведёт программа? Функции: malloc(), realloc(), free()
Почему большинство значений в output 0 и несколько из значений не равно 0? /* *...

Malloc в процедуре - почему не работает передача указателя
Доброго времени суток, есть такой код: #include <stdio.h> #include <stdlib.h> void getInput...

Почему работает не так как надо?
В общем вот в чем вопрос, есть код на СИ. Задача такова ввести с клавы день, месяц, год рождения...

Как работает функция malloc?
Добрый день. Кто - нибудь может рассказать как работает функция malloc ? Вот набрал код...

13
Mirmik
techpriest
631 / 210 / 57
Регистрация: 27.02.2014
Сообщений: 1,163
08.03.2016, 14:10 2
А не так, это как?
0
zss
Модератор
Эксперт С++
9082 / 7871 / 4852
Регистрация: 18.12.2011
Сообщений: 20,997
Завершенные тесты: 1
08.03.2016, 14:13 3
C++
1
2
3
4
    int* p =malloc(sizeof(int)*101);
....
free(p);
return 0;
0
DavidTs
3 / 3 / 8
Регистрация: 25.11.2015
Сообщений: 127
08.03.2016, 14:19  [ТС] 4
Mirmik, I gave memory just for one integer and initialized the 100th element, but it works correctly.

Добавлено через 3 минуты
zss, это понятно, я так сделал специально, чтобы получить ошибку, но почему errno возвращает success?
0
08.03.2016, 14:19
Nick Alte
Эксперт С++
1657 / 1029 / 174
Регистрация: 27.09.2009
Сообщений: 1,945
Завершенные тесты: 1
08.03.2016, 14:20 5
DavidTs, это undefined behavior. Никто специальную проверку не делает, выходит ли программист за пределы массива или нет, ошибку такую не ловит. Было бы затратно на каждое обращение к массиву и прочие элементарные действия лепить проверки и диагностики. Предполагается, что программист сам принимает меры и пишет программу корректно.
1
Mirmik
techpriest
631 / 210 / 57
Регистрация: 27.02.2014
Сообщений: 1,163
08.03.2016, 14:45 6
DavidTs На самом деле, malloc особенно ничего не делает. Он следит только затем, чтобы в следующий раз не выдать указатель на ту же ячейку памяти. Это уведомительная операция.

Вы сказали:
- Эй Маллок, куда мне положить мой объект размера int.
- Клади сюда, - сказал Маллок и отвернулся...

А вы пошли в другую сторону и положили свой инт еще куда-то... Вот собственно и всё, никто вам этого не запрещает.
0
Хрисипп
19 / 29 / 13
Регистрация: 09.02.2016
Сообщений: 219
08.03.2016, 17:01 7
вообще тут интересные вещи происходят. Когда ты обратился к элементу несуществующего массива, создался этот массив, но он забрал все доступное ему место(не знаю от чего зависит,но в C++ выделилось раза в два больше места). НО это происходит только с указателями и только,если этот самый указатель пустой и под него выделено место

...даже и не знаю где про это можно почитать
0
TheCalligrapher
С чаем беда...
Эксперт CЭксперт С++
6110 / 2903 / 789
Регистрация: 18.10.2014
Сообщений: 5,320
08.03.2016, 20:00 8
Уже сто раз об этом писали в соседней ветке
Память освобождается, но значение остается
Память освобождается, но значение остается

Защита памяти от некорректного доступа выполняется на уровне ОС. Библиотека времени выполнения (БВВ) не передает каждый из ваших 'malloc'-ов в ОС, а просто сначала запрашивает у ОС один большой блок памяти, внутри которого уже БВВ сама занимается раздачей памяти под ваши маленькие объекты. Поэтому пока вы своим некорректным доступом попадаете внутрь этого большого блока, нарушения защиты памяти происходить не будет (с точки зрения ОС все в порядке) и будет даже казаться, что "все работает".

А сделайте ваш индекс побольше - так, чтобы доступ вылез за пределы изначально запрошенного у ОС блока памяти - и этот пример сразу же накроется медным тазом, потому что сработает защита памяти уровня ОС.

Разумеется, говорить, что исходный пример "работает" - наивная ерунда. Поведение программы в любом случае не определено. Вы лезете в память, которая вам не принадлежит и с рук вам это сходит только в вашем искуственном микроскопическом примере. В реальной программе дело закончится существенно более печально: либо вы разрушите "чужие" данные, либо в будущем новый запрос памяти будет размещен в этом месте и разрушит ваши данные.

Добавлено через 3 минуты
Цитата Сообщение от Хрисипп Посмотреть сообщение
вообще тут интересные вещи происходят. Когда ты обратился к элементу несуществующего массива, создался этот массив, но он забрал все доступное ему место
Ничего подобного здесь, разумеется, не происходит и никакого массива, который "забрал все доступное ему место" не создается. Все здесь просто, банально и уже давно разжевано вдоль и поперек. Непонятно, почему такие темы до сих пор вызывают у кого-то такое недоумение.
0
DavidTs
3 / 3 / 8
Регистрация: 25.11.2015
Сообщений: 127
08.03.2016, 20:07  [ТС] 9
nick]Mirmik[/nick], TheCalligrapher, Спасибо. А здесь по той же причине после второго вызова calloc () sbrk не перемещается?
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <stdio.h>
#include <stdlib.h>
 
 
int main()
{
    printf("first_brk __ %p\n",sbrk(0));
    int* ptr = calloc(5,sizeof(int));
    printf("ptr = %p\n", ptr);
 
    printf("after_first_alloc_brk __ %p\n",sbrk(0));
 
    char* char_ptr = calloc(3,sizeof(char));
    printf("char_ptr = %p\n",char_ptr);
    printf("after_second_alloc_brk __ %p\n",sbrk(0));
    return 0;
}
0
TheCalligrapher
С чаем беда...
Эксперт CЭксперт С++
6110 / 2903 / 789
Регистрация: 18.10.2014
Сообщений: 5,320
08.03.2016, 20:41 10
Лучший ответ Сообщение было отмечено DavidTs как решение

Решение

Цитата Сообщение от DavidTs Посмотреть сообщение
А здесь по той же причине после второго вызова calloc () sbrk не перемещается?
Совершенно верно. Как вы видите, что при первом вызове 'calloc' 'sbrk' перемещается на существенно большее расстояние чем нужно было. Например здесь он перемещается на ~135Kb, хотя попросили вы всего ~20 байт. Это и есть память, заранее отхваченная у системы "на будущее". И пока она вся не распределится внутренними механизмами БВВ, перемещения 'sbrk' наблюдаться не будет (по крайней мере для мелких запросов).
0
DavidTs
3 / 3 / 8
Регистрация: 25.11.2015
Сообщений: 127
08.03.2016, 21:25  [ТС] 11
TheCalligrapher, спасибо за объяснение.
0
Хрисипп
19 / 29 / 13
Регистрация: 09.02.2016
Сообщений: 219
09.03.2016, 12:57 12
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Ничего подобного здесь
почему же он позволяет обратиться к массиву? с переменной же такое не прокатит
0
TheCalligrapher
С чаем беда...
Эксперт CЭксперт С++
6110 / 2903 / 789
Регистрация: 18.10.2014
Сообщений: 5,320
10.03.2016, 01:46 13
Цитата Сообщение от Хрисипп Посмотреть сообщение
почему же он позволяет обратиться к массиву? с переменной же такое не прокатит
Не понимаю, о чем речь. Приведите примеры "позволяет" и "не прокатит".
0
Хрисипп
19 / 29 / 13
Регистрация: 09.02.2016
Сообщений: 219
12.03.2016, 14:35 14
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Приведите примеры
как-то много вопросов возникает, чтобы нормально ответить. лучше уж пойти мне, ламеру, поучиться
0
12.03.2016, 14:35
Answers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
12.03.2016, 14:35

Как в приведенном коде работает malloc?
#include &lt;stdio.h&gt; #include &lt;memory.h&gt; #include &lt;stdlib.h&gt; #include &lt;string.h&gt; #include...

Почему цикл работает не так, как ожидается?
Двумя способами реализовал цикл, который увеличивает годовую зарплату на 10% при нажатии 'y' до тех...

Объяснить, почему программа для подсчёта скобок в тексте работает не так, как ожидается
я ввожу текст в блокноте с скобками, мне нужно подсчитать количество скобок в программе, но у меня...


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

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

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