powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / malloc(0)
15 сообщений из 15, страница 1 из 1
malloc(0)
    #39022182
vvm46
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Код: plaintext
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.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
#include <iostream>
#include <malloc.h>

using namespace std;

int main()
{

/*
Докапываюсь до истины.
Вопрос malloc(0) возвращает указатель на участок памяти размером 0?
По идее malloc(size_t size);

выделяем память для указателя типа char нулевого размера
память  выделилась и мы можем это проверить

Как я понимаю в первом случае получаем указатель на участок памяти размером =0
и поэтому память распределилась и мы получили указаеть на начало блока памяти размером 0
далее мы заносим в этот учаток буквочку 'r'
то есть память уже расширяется. тоже нужно проверить sizeof();
Что это значит?
Мы не распределили память нулевого размера, а компилятор как-то догадался выделить память размером 8?

Возникает вопрос, почему компилятор не заругался на malloc(0); ???
Какого размера память он выделил?
*/
char *ptr;
if ( (ptr = (char *)malloc(0)) == NULL )
    {
       //puts(“Got a null pointer”);
       cout<<"Got a null pointer\n";
    }
else
    {
       //puts(“Got a valid pointer”);
        cout<<"Got a valid pointer\n";
    }
 cout<<"sizeof(ptr)="<<sizeof(ptr)<<"\n";
// раз уж память распределилась то занесем туда что-то
//*ptr=(char)'r';
*ptr= 'r';
 cout<<"и размер стал sizeof(ptr)="<<sizeof(ptr)<<"\n";
// что у нас в указателе?
  cout<<"в указателе сидит вот что = "<<(char)(*ptr)<<"\n";

//освободим память и обнулим указатель
free(ptr); *ptr=0;
// вторая попытка
if ( (ptr = (char *)malloc(sizeof(char))) == NULL )
    {
       //puts(“Got a null pointer”);
       cout<<"+Got a null pointer\n";
    }
else
    {
       //puts(“Got a valid pointer”);
        cout<<"+Got a valid pointer\n";
    }

    // раз мы освободили память, то занесем туда что-то
    //
*ptr=(char)'n';
// что у нас теперь в указателе?
  cout<<" теперь в указателе сидит вот что = "<<(char)(*ptr)<<"\n";
free(ptr);*ptr=0;

// третий вариант размер 0 - 4  - у нас выделился участок памяти размером 4, но в указатель попадает 8
if ( (ptr = (char *)malloc( (size_t)0 )) == NULL )
    {
       //puts(“Got a null pointer”);
       cout<<"++Got a null pointer\n";
    }
else
    {
       //puts(“Got a valid pointer”);
        cout<<"++Got a valid pointer\n";
    }

    cout<<"sizeof(size_t) = "<<sizeof(size_t) << "  sizeof(0)  =  " <<sizeof(0)<<"\n";
    cout << " у нас выделился участок памяти =" <<sizeof(ptr)<<"\n";


free(ptr);*ptr=0;
    return 0;
}
...
Рейтинг: 0 / 0
malloc(0)
    #39022199
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vvm46,

Cтандарт ISO/IEC 9899:201x 7.22.3 Memory managment function говорит (перевожу, ибо скопировать текст не могу, пропала такая функция):
Если размер запрашиваемой области памяти равен нулю, поведение определяется реализацией: либо возвращается нулевой указатель, либо поведение соответствует запросу на выделение непустой области памяти, за исключением того, что возвращаемое значение не должно быть использовано для доступа.
...
Рейтинг: 0 / 0
malloc(0)
    #39022200
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если реализация ведёт себя последним способом то становятся доступными операции реаллоцирования и освобождения памяти по вернувшемуся адресу.
...
Рейтинг: 0 / 0
malloc(0)
    #39028980
vvm46
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Спасибо за разъяснения. Вот еще нашел, в продолжение.
Почему размер пустого класса не нулевой?
Ответ на сайте Bjarne Stroustrup
http://www.stroustrup.com/bs_faq2.html

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

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
class Empty { };

	void f()
	{
		Empty a, b;
		if (&a == &b) cout << "impossible: report error to compiler supplier";

		Empty* p1 = new Empty;
		Empty* p2 = new Empty;
		if (p1 == p2) cout << "impossible: report error to compiler supplier";
	}	




Это интересное правило, которое говорит, что пустой базовый класс не должен быть представлен отдельным байтом:


Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
struct X : Empty {
		int a;
		// ...
	};

	void f(X* p)
	{
		void* p1 = p;
		void* p2 = &p->a;
		if (p1 == p2) cout << "nice: good optimizer";
	}


Эта оптимизация является безопасной и может быть наиболее полезной.

Это позволяет программисту использовать пустые классы, представляющие собой очень простые понятия,без накладных расходов.
Некоторые современные компиляторы предоставляют это : «оптимизацию пустых базовых классов".

PS. Тут я воплотил код в программе и прокомментировал:

Код: plaintext
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.
31.
32.
33.
#include <iostream>

/* 
оригинал:http://www.stroustrup.com/bs_faq2.html
*/
using namespace std;

struct Empty{}; // некоторая пустая структура


// наследуем структуру от пустой
struct X : Empty {
		int a;
		// ...
	};

//передаем указаетль на нашу структуру для сравнения
	void f(X* p)
	{
		void* p1 = p;           // указатель на струкруру
		void* p2 = &p->a;      // указатель на адрес эемента а в структуре
		if (p1 == p2) cout << "nice: good optimizer"; //сравнение указателей
	}

int main()
{

X *myX =new X; //создали указатель на структуру
f(myX); // передали указатель на структуру в функцию


    return 0;
}
...
Рейтинг: 0 / 0
malloc(0)
    #39029126
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vvm46,

ну раз вы разобрались в проблеме, то

1)vvm46 По той же причине, "новый" всегда возвращает указатели на различные объекты
имя оператора пожалуй не следовало переводить.
2) vvm46Это интересное правило, которое говорит, что пустой базовый класс не должен быть представлен отдельным байтом:

непонятно что вы имеете ввиду. Объясните пожалуйста подробнее
...
Рейтинг: 0 / 0
malloc(0)
    #39029128
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
И вообще говоря было бы странно если бы оператор new возвращал одинаковые значения (кроме ex и ub).
...
Рейтинг: 0 / 0
malloc(0)
    #39029826
vvm46
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
SashaMercuryvvm46,

ну раз вы разобрались в проблеме, то

1)vvm46 По той же причине, "новый" всегда возвращает указатели на различные объекты
имя оператора пожалуй не следовало переводить.
2) vvm46Это интересное правило, которое говорит, что пустой базовый класс не должен быть представлен отдельным байтом:

непонятно что вы имеете ввиду. Объясните пожалуйста подробнее

Это не я имею в виду, а Bjarne Stroustrup:
"There is an interesting rule that says that an empty base class need not be represented by a separate byte:
Дальше код по тексту.
"
Вот ссылка на оригинал : http://www.stroustrup.com/bs_faq2.html#sizeof-empty

Очевидно он имет в виду оптимизацию, я так понимаю.
И при хорошей оптимизации указатель ссылающийся на пустой класс будет равен указателю на член унаследованного класса.
То есть это не раздельные адресованные байты. А один и тот же адрес.
...
Рейтинг: 0 / 0
malloc(0)
    #39029831
vvm46
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
SashaMercury,
"имя оператора пожалуй не следовало переводить."
Справедливое замечание.
"new" в данном контексте следует так и читать: "new", так как это оператор.
Кнопки "редактировать свой ответ" нет на форуме?
...
Рейтинг: 0 / 0
malloc(0)
    #39029888
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vvm46,
изменять свои сообщения нельзя.
Мне не понятно что это даёт, и о чём хотел сказать автор языка. Поясните кто-нибудь пожалуйста, для 'особо одаренных'. В чём собственно соль ?
...
Рейтинг: 0 / 0
malloc(0)
    #39029889
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SSvvm46,
изменять свои сообщения нельзя.


точнее 99,9 процентам пользователей нельзя.
...
Рейтинг: 0 / 0
malloc(0)
    #39029899
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vvm46Спасибо за разъяснения. Вот еще нашел, в продолжение.
Почему размер пустого класса не нулевой?
Ответ на сайте Bjarne Stroustrup
http://www.stroustrup.com/bs_faq2.html

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


Объясню проще. Из объектов любого типа можно сделать массив. Адреса соседних элементов массива различаются на размер объекта в памяти. Если этот размер нулевой, то два соседних элемента массива будут иметь один и тот же адрес, а это нарушение одного
из главных принципов ООП -- объект в программе должен быть идентифицируем.

Поэтому все правила формирования объектов добавляются в стандарте ещё одним правилом -- финальный размер объекта при любых наследованиях и упаковках должен быть больше нуля.

При этом если есть пустой неполиморфный класс, размер его объекта будет 1 байт, если есть ещё и пустой его наследник, то размер наследника не будет 2 -- он будет всё равно 1.
...
Рейтинг: 0 / 0
malloc(0)
    #39029914
vvm46
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
MasterZiv, Спасибо за разъяснения.
Теперь понятно, почему указатели в коде примера получились равны.
...
Рейтинг: 0 / 0
malloc(0)
    #39030765
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Здравствуйте.
Илья, спасибо, частично мне понятно то о чём вы говорили.
А разве может быть в других парадигмах программирования неоднозначная идентификация объекта ?
...
Рейтинг: 0 / 0
malloc(0)
    #39030788
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercury
А разве может быть в других парадигмах программирования неоднозначная идентификация объекта ?

Нет.
Вообще "объект" -- это в общем, что-то с чем программа оперирует. Она чтобы это делать должна уметь идентифицировать
объект однозначно. В некоторых языках идентификатором является адрес в памяти, в других -- идентификатор в виртуальной памяти виртуальной машины, и т.п. Но в любом случае этот идентификатор должен быть. Тут говорилось мной об ООП только потому, что
С++-- объектноориентированный язык прогр. и "объект" -- это из ООП.
Но тем не менее в ООП независимо от С++ существует обязательное требование идентифицируемости объектов.
...
Рейтинг: 0 / 0
malloc(0)
    #39030793
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivSashaMercury
А разве может быть в других парадигмах программирования неоднозначная идентификация объекта ?

Нет.
Вообще "объект" -- это в общем, что-то с чем программа оперирует. Она чтобы это делать должна уметь идентифицировать
объект однозначно. В некоторых языках идентификатором является адрес в памяти, в других -- идентификатор в виртуальной памяти виртуальной машины, и т.п. Но в любом случае этот идентификатор должен быть. Тут говорилось мной об ООП только потому, что
С++-- объектноориентированный язык прогр. и "объект" -- это из ООП.
Но тем не менее в ООП независимо от С++ существует обязательное требование идентифицируемости объектов.

Это одно из требований образующих полноту теории ООП, вероятно. Спасибо C:
...
Рейтинг: 0 / 0
15 сообщений из 15, страница 1 из 1
Форумы / C++ [игнор отключен] [закрыт для гостей] / malloc(0)
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]