Russian Qt Forum
Ноябрь 24, 2024, 00:34 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: 1 ... 4 5 [6] 7   Вниз
  Печать  
Автор Тема: как правильней писать указатель?  (Прочитано 42087 раз)
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #75 : Февраль 17, 2011, 14:17 »

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

По стандарту это UB, имеют право хоть выдать "hello world". Я думаю в релиз-версии не так.
То да, но ведь отлаживаться-то надо. Ну настроить это все конечно можно, но когда с десяток хороших (и чужих) static lib - наступает звериный кайф. Попробуйте откомпилить хоть одну либу "не так" - и sizeof самого контейнера не сбивается. И такие "вытекающие" что вначале только рот разеваешь  Обеспокоенный

Еще деталька/вопрос:

Стандартный контейнер(ы) испускает exception в случае отказа памяти. Это нормально/разумно, но не всегда устраивает. Напр. если я получил отказ я могу потеснить кэш или др. ресурсы и затем повторить. Словом мне надо чтобы возвращался NULL. "Одевать" каждый push_back в блок try/catch коряво (да и дорого). Какие есть решения?

Спасибо
Записан
BRE
Гость
« Ответ #76 : Февраль 17, 2011, 14:23 »

Блин, не то сообщение отредактировал.  Улыбающийся
« Последнее редактирование: Февраль 17, 2011, 16:59 от BRE » Записан
BRE
Гость
« Ответ #77 : Февраль 17, 2011, 14:25 »

Да как будто я выбираю "пользоваться или нет"  Плачущий
Не обязательно пользоваться STL от microsoft. Есть и другие, вроде даже под VS.
Записан
brankovic
Гость
« Ответ #78 : Февраль 17, 2011, 14:37 »

Дома проверю еще на 64 битах.

На убунту 10.10 64 бит работает как у вас, это интересно, не знаю как и объяснить.

Словом мне надо чтобы возвращался NULL. "Одевать" каждый push_back в блок try/catch коряво (да и дорого). Какие есть решения?

Многие методы не возвращают (void push_back), соответственно так сделать нельзя. Но можно переопределить аллокатор, чтобы он пытался лезьть в кэши и их чистить, а исключение кидалось только если почистить не получилось. Не очень хороший вариант, но лучше не знаю.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #79 : Февраль 17, 2011, 14:42 »

Полемика насчет нюансов страниц, на мой взгляд, беспредметна. В свое время я проверял на своей платформе (Mac OSX) и получил те же результаты что и brankovic. Очень может быть что на др. платформе это не так, и что с того? Гораздо проще/практичнее допустить "неиспользуемые хвостики" (так или иначе они неизбежны) чем долго морочить себе голову в нюансах ОС которые могут и поменяться.

Вообще если структура 1K и более - с ней проблем не возникает, да просто вектор указателей - и все дела. Речь идет о примитивных данных которые однако могут поступать в громадных количествах - и с этим надо что-то делать.
Записан
Кутенок
Гость
« Ответ #80 : Февраль 17, 2011, 14:43 »

Код:
#include <iostream>
int main()
{
// XP, VS 2008 Express, свойства проекта по умолчанию
// Объем используемой памяти в диспетчере задач:
//int blockSize = 1; // 33128 KB
//int blockSize = 10; // 41168 KB
int blockSize = 100; // 129316 KB
// Вывод: нет выравнивания по страницам памяти
// А лишние 30 MB видимо используются для учета 1 млн. блоков
for(int i = 0; i<1000*1024; ++i)
malloc(blockSize);
std::cin.get();
return 0;
}
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #81 : Февраль 17, 2011, 14:49 »

Цитировать
Не все так однозначно.
RHEL-x86:
0x8fc7008 150761480 +7
0x8fd1010 150802448 +7

RHEL-x86_64:
0x502010 5251088 +15
0x50c020 5292064 +15

Цитировать
На убунту 10.10 64 бит работает как у вас, это интересно, не знаю как и объяснить.
Просто везде используются разные memory manager-ы. Про юбунту не скажу, а вот на FreeBSD свой и совсем не такой как в линуксе.

Записан

Qt 5.11/4.8.7 (X11/Win)
brankovic
Гость
« Ответ #82 : Февраль 17, 2011, 14:52 »

Код:
#include <iostream>
int main()
{
// XP, VS 2008 Express, свойства проекта по умолчанию
// Объем используемой памяти в диспетчере задач:
//int blockSize = 1; // 33128 KB
//int blockSize = 10; // 41168 KB
int blockSize = 100; // 129316 KB
// Вывод: нет выравнивания по страницам памяти
// А лишние 30 MB видимо используются для учета 1 млн. блоков
for(int i = 0; i<1000*1024; ++i)
malloc(blockSize);
std::cin.get();
return 0;
}

Ну так блок-то маленький, 100 байт всего -- неправильный пример.

Вообще в обсуждении о том 'как на самом деле' и правда нет смысла, всё равно считается всё в страницах в конечном итоге. Если malloc не устраивает, то всегда можно прибегнуть к прямому захвату в обход malloc.

Просто везде используются разные memory manager-ы. Про юбунту не скажу, а вот на FreeBSD свой и совсем не такой как в линуксе.

На прошлой работе в центосах работало как я говорил. Кто такие вообще мемори менеджеры? Мы говорили о реализации malloc что в libc
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #83 : Февраль 17, 2011, 14:56 »

Цитировать
Кто такие вообще мемори менеджеры? Мы говорили о реализации malloc что в libc
Ну это и имелось в виду.
Записан

Qt 5.11/4.8.7 (X11/Win)
Кутенок
Гость
« Ответ #84 : Февраль 17, 2011, 16:31 »

Код:
#include <iostream>
int main()
{
// XP, VS 2008 Express, свойства проекта по умолчанию
// Объем используемой памяти в диспетчере задач:
//int blockSize = 4096-1; // 42356 КB
//int blockSize = 4096; // 42356 КB
//int blockSize = 4096+1; // 42436 KB
//int blockSize = 4096+8; // 42436 KB
//int blockSize = 4096+9; // 42524 KB
// Вывод: нет выравнивания по страницам памяти, но адреса выравниваются к границе 8 байт
for(int i = 0; i<10*1024; ++i)
malloc(blockSize);
std::cin.get();
return 0;
}
Записан
brankovic
Гость
« Ответ #85 : Февраль 17, 2011, 16:54 »

Вывод: нет выравнивания по страницам памяти

вывод неправильный. Правильный вывод, что при размере блока в 4096 байт нет выравнивания. Проверять надо для реально большого блока, например 4096 * 1024. Кроме того надо делать не +8 а минус -8, поскольку выделенный блок имеет заголовок минимум в 8 байт. Для надёжности я бы сделал +-100.

, но адреса выравниваются к границе 8 байт

это свойство malloc, по стандарту он обязан возвращать память с выравниванием подходящим для любого типа на этой архитектуре.
Записан
BRE
Гость
« Ответ #86 : Февраль 17, 2011, 16:59 »

Дома проверю еще на 64 битах.
[/qoute]
Цитировать
[...]$ ./a.out
0x1150010 18153488 +15
0x115a020 18194464 +15
0x1164030 18235440
[...]$ g++ -v
Используются внутренние спецификации.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-unknown-linux-gnu/4.5.2/lto-wrapper
Целевая архитектура: x86_64-unknown-linux-gnu
Параметры конфигурации: /build/src/gcc-4.5-20110127/configure --prefix=/usr --enable-languages=c,c++,fortran,objc,obj-c++,ada --enable-shared --enable-threads=posix --enable-__cxa_atexit --enable-clocale=gnu --enable-gnu-unique-object --enable-lto --enable-plugin --enable-gold --with-plugin-ld=ld.gold --disable-multilib --disable-libstdcxx-pch --with-system-zlib --with-ppl --with-cloog --with-cloog-include=/usr/include/cloog-ppl --libdir=/usr/lib --libexecdir=/usr/lib --mandir=/usr/share/man --infodir=/usr/share/info
Модель многопоточности: posix
gcc версия 4.5.2 20110127 (prerelease) (GCC)
[...]$
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #87 : Февраль 17, 2011, 17:17 »

вывод неправильный. Правильный вывод, что при размере блока в 4096 байт нет выравнивания. Проверять надо для реально большого блока, например 4096 * 1024. Кроме того надо делать не +8 а минус -8, поскольку выделенный блок имеет заголовок минимум в 8 байт. Для надёжности я бы сделал +-100.
Мое мнение - Вы напрасно усложняете. Просто размер "реально выделенного (используемого)" + "служебные байты" должен  быть кратен 4K, но не превышать его. Это легко сделать. Потеряли несколько байт - переживем, на chunk'е 64K это нормально
Записан
BRE
Гость
« Ответ #88 : Февраль 17, 2011, 17:20 »

Потеряли несколько байт - переживем, на chunk'е 64K это нормально
А почему это нормально? Почему именно 64K это нормально, а 128К, 512К, это нормально или уже нет?
Какой критерий?
Записан
Кутенок
Гость
« Ответ #89 : Февраль 17, 2011, 17:38 »

Цитировать
#include <iostream>
int main()
{
   // XP, VS 2008 Express, свойства проекта по умолчанию
   // Объем используемой памяти в диспетчере задач:
   //int blockSize = 3*(4096-100); // 121496 КB
   int blockSize = 3*(4096+100); // 127536 KB
   for(int i = 0; i<10*1024; ++i)
      malloc(blockSize);
   std::cin.get();
   return 0;
}

Идея о том, что когда машина увидит РЕАЛЬНО большой блок памяти, то перестанет мелочиться, кажется мне очень "человечной".

Интересно, что если просто свернуть окно консоли, не завершая программы, то вся память освобождается. Как VS это делает?
« Последнее редактирование: Февраль 17, 2011, 17:42 от Кутенок » Записан
Страниц: 1 ... 4 5 [6] 7   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.091 секунд. Запросов: 23.