Доброго всем.
Что то вчера навеяло читал мельком на хабре про с++ стат.анализ.
Пишут — этот код некорректный
std::shared_ptr<int> ss(new int[decks * 52]);
Предупреждение PVS-Studio: V554 Incorrect use of shared_ptr. The memory allocated with 'new []' will be cleaned using 'delete'. BlackJack_Server140 table.cpp 471
Я просто когда пишу знаю что тут у меня тип POD, и не делаю delete [], все равно то new->malloc, delete[]->free
И главное — я знаю где POD, а где конструктор, т.е. детской ошибки не получу
А что вы думаете — просто поразмышлять
P.S. Да еще при компиляции
delete []
время требует наверное больше?? Хотя утверждать не буду.
Здравствуйте, PowerUserX, Вы писали:
PUX>Пишут — этот код некорректный
правильно пишут
PUX>А что вы думаете — просто поразмышлять
я думаю, что обязательно соблюдать парность new[]/delete[], иначе это UB (сегодня для POD работает любой вариант, завтра не работает. сегодня это POD — завтра не POD) и говорит о непрофессионализме разработчика
PUX>P.S. Да еще при компиляции
delete []
время требует наверное больше??
не слышал о таком и не вижу причин для этого
new->malloc, delete[]->free — это крайне грубые ошибки.
Сегодня вы знаете где POD, а завтра кто-то заменит этот POD на не POD и вы все вместе сядите в лужу.
Освобождающий память метод всегда должен соответствовать методу, выделившему ее, так что диагностика однозначно полезная.
На скорость компиляции это все никаким заметным образом не влияет.
Хотя страдальцам, у которых все часами компилируются, будет не легче.
Говорить дальше не было нужды. Как и все космонавты, капитан Нортон не испытывал особого доверия к явлениям, внешне слишком заманчивым.
VTT>даже не соберется, так как не все параметры шаблона указаны.
у shared_ptr один шаблонный параметр, см. http://en.cppreference.com/w/cpp/memory/shared_ptr
то, о чем вы пишете, актуально для std::unique_ptr. в нем явно надо указать тип deleter-а, в shared_ptr используется type-erasure и надобности указывать тип deleter-а нет
Здравствуйте, uzhas, Вы писали:
U>Здравствуйте, PowerUserX, Вы писали:
PUX>>Пишут — этот код некорректный U>правильно пишут
PUX>>А что вы думаете — просто поразмышлять U>я думаю, что обязательно соблюдать парность new[]/delete[], иначе это UB (сегодня для POD работает любой вариант, завтра не работает. сегодня это POD — завтра не POD) и говорит о непрофессионализме разработчика
PUX>>P.S. Да еще при компиляции
delete []
время требует наверное больше?? U>не слышал о таком и не вижу причин для этого
POD — это просто память, кусок выделил — занулил — использовал — удалил
Пока есть текущая память = true || false — наши программы на С++ компилятся
А вот если мы переедем на квантовый компьютер — то наши программы не скомпилятся
там другая модель памяти
PUX>Я просто когда пишу знаю что тут у меня тип POD, и не делаю delete [], все равно то new->malloc, delete[]->free
А потом кто-то добавляет в проект навороченный аллокатор, который по-разному обрабатывает malloc и new[] -- и приплыли.
или кто-то переопределил new / delete но не стал трогать malloc / free -- и опять чудеса.
нет уж, парность надо соблюдать
template< class T >
unique_ptr<T> make_unique( std::size_t size );
Пример:
auto array = std::make_unique<int[]>(42);
Здесь создается объект array класса std::unique_ptr<int[]>, хранящий указатель на динамический массив из 42 элементов типа int. Эдакая легковесная замена std::dynarray.
Здравствуйте, PowerUserX, Вы писали:
PUX>Я просто когда пишу знаю что тут у меня тип POD, и не делаю delete [], все равно то new->malloc, delete[]->free PUX>И главное — я знаю где POD, а где конструктор, т.е. детской ошибки не получу
Такой гарантии нет. То, что текущая версия твоего компилятора и Фреймворка это позволяет, ничего не гарантирует...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, uzhas, Вы писали:
U>то, о чем вы пишете, актуально для std::unique_ptr. в нем явно надо указать тип deleter-а, в shared_ptr используется type-erasure и надобности указывать тип deleter-а нет
Но таки надо передать в конструктор делетер массива...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, PowerUserX, Вы писали:
PUX>POD — это просто память, кусок выделил — занулил — использовал — удалил
Ну так и выделяй по alloc, а освобождай по free
PUX>Так что POD был ... есть ... и будет есть
Проблема в том, что кто-то, включая автором стандартной библиотеки для твоего компилятора, могут наделить operator new[] и operator delete[] каким-то особым поведением. Например, могут класть куда-то ПЕРЕД буфером его длину или число элементов в new[], а в delete[] это как-то использовать...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Stanislav V. Zudin, Вы писали:
SVZ>А у меня другой вопрос. Так сказать, для расширения кругозора. Почему не std::vector<int>?
Наверное потому, что он shared не умеет...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Erop, Вы писали:
E>Здравствуйте, PowerUserX, Вы писали:
PUX>>POD — это просто память, кусок выделил — занулил — использовал — удалил E>Ну так и выделяй по alloc, а освобождай по free
PUX>>Так что POD был ... есть ... и будет есть
E>Проблема в том, что кто-то, включая автором стандартной библиотеки для твоего компилятора, могут наделить operator new[] и operator delete[] каким-то особым поведением. Например, могут класть куда-то ПЕРЕД буфером его длину или число элементов в new[], а в delete[] это как-то использовать...
Проблемы нет, перед пусть кладут что угодно
Все API Linux, Win, OsX .... аперирует входными параметрами (char* pBuff, int len ) — и это POD — плоская память
И это на наших компах будет всегда — для кубитов в квантовом компе енто не покатит
Вот поэтому
Мне иногда короче писать
auto pBuffer = new int[32];
char* pBuffer = (char*)malloc(32 * sizeof(int));
^
|
| — тут длиннее
и вот зачем мне писать delete [] pBuffer ?
P.S. Честно я все это писал немного шоб потролить — у нас тут все крутые
Ночью разбуди
— Что написано в стандарте на странице 485?
— .....
Здравствуйте, PowerUserX, Вы писали:
PUX>Проблемы нет, перед пусть кладут что угодно
Смотри, ты попросил в new int[32] 128 байт памяти, а operator new[] взял, да и выделил 132. В первые 4 положил что-то там своё, а тебе вернул адрес пятого (то есть реальный адрес блока + 4)
Если ты позовёшь с эти адресом operator delete[], то он 4 вычтет, свои данные найдёт и всё правильно сделает. В том числе и освободит ВЕСЬ блок.
А если ты позовёшь operator delete, то он просто освободит часть блока, вернее попытается, и всё...
То есть ситуация получится примерно такая:
struct XXX {
int hiddenField;
int array[32];
};
int* array = new XXX->array;
delete array; // Упс
PUX>auto pBuffer = new int[32]; PUX>char* pBuffer = (char*)malloc(32 * sizeof(int)); PUX> ^ PUX> | PUX> | — тут длиннее
PUX>и вот зачем мне писать delete [] pBuffer ?
Ну успехов тебе в труде. Не забудь прислать этот пример оригинальности и свежести своего мышления в своё партфолио и приложить к резюме, когда будешь искать след. работу...
PUX>P.S. Честно я все это писал немного шоб потролить — у нас тут все крутые
Я уже что-то начал подозревать
Держись в общем тут, и хорошего тебе настроения
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Erop, Вы писали:
SVZ>>А у меня другой вопрос. Так сказать, для расширения кругозора. Почему не std::vector<int>? E>Наверное потому, что он shared не умеет...
Здравствуйте, Erop, Вы писали:
E>Здравствуйте, PowerUserX, Вы писали:
PUX>>Проблемы нет, перед пусть кладут что угодно E>Смотри, ты попросил в new int[32] 128 байт памяти, а operator new[] взял, да и выделил 132. В первые 4 положил что-то там своё, а тебе вернул адрес пятого (то есть реальный адрес блока + 4) E>Если ты позовёшь с эти адресом operator delete[], то он 4 вычтет, свои данные найдёт и всё правильно сделает. В том числе и освободит ВЕСЬ блок. E>А если ты позовёшь operator delete, то он просто освободит часть блока, вернее попытается, и всё...
Согласен.
E>То есть ситуация получится примерно такая:
struct XXX {
E> int hiddenField;
E> int array[32];
E>};
E>int* array = new XXX->array;
E>delete array; // Упс
PUX>>auto pBuffer = new int[32]; PUX>>char* pBuffer = (char*)malloc(32 * sizeof(int)); PUX>> ^ PUX>> | PUX>> | — тут длиннее
PUX>>и вот зачем мне писать delete [] pBuffer ? E>Ну успехов тебе в труде. Не забудь прислать этот пример оригинальности и свежести своего мышления в своё партфолио и приложить к резюме, когда будешь искать след. работу...
Надо ж както развлекаться — а то сгоришь
PUX>>P.S. Честно я все это писал немного шоб потролить — у нас тут все крутые E>Я уже что-то начал подозревать E>Держись в общем тут, и хорошего тебе настроения
Здравствуйте, B0FEE664, Вы писали:
BFE>PS Хотя, конечно, new надо на std::make_shared заменить:
BFE>
BFE>auto ss = std::make_shared< std::vector<int> >(decks * 52);
BFE>
Это, какой-то недописсемизированный вариант, я щитаю...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском