Чем искать банальную утечку
От: кубик  
Дата: 10.04.15 04:58
Оценка:
Привет

Подскажите чем можно найти такие ошибки копипейста:

void * a = func1();
if (..){
....
void * a= func2();
}
delete a;

Предполадается что в if блоке надо было "a= func2();"
Re: Чем искать банальную утечку
От: placement_new  
Дата: 10.04.15 05:03
Оценка: 8 (1) +1
Здравствуйте, кубик, Вы писали:

К>Привет


К>Подскажите чем можно найти такие ошибки копипейста:


К>void * a = func1();

К>if (..){
К> ....
К> void * a= func2();
К>}
К>delete a;

К>Предполадается что в if блоке надо было "a= func2();"


valgrind.
PS все равно была бы утечка.
Re: Чем искать банальную утечку
От: fdn721  
Дата: 10.04.15 05:09
Оценка: 9 (2)
Здравствуйте, кубик, Вы писали:

К>Привет


К>Подскажите чем можно найти такие ошибки копипейста:


VLD
Re: Чем искать банальную утечку
От: кубик  
Дата: 10.04.15 05:35
Оценка:
А статичный анализатор для Visual studio на такое хотя бы обратит внимание? Если да, то какой порекомендуете?
Re: Чем искать банальную утечку
От: jazzer Россия Skype: enerjazzer
Дата: 10.04.15 06:04
Оценка: 8 (1)
Здравствуйте, кубик, Вы писали:

К>void * a = func1();

как насчет переписать на смарт-пойнтеры?
std::unique_ptr<...> a{func1()};
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re: Чем искать банальную утечку
От: Mazay Россия  
Дата: 10.04.15 08:20
Оценка:
Здравствуйте, кубик, Вы писали:

clang LeakSanitizer
Главное гармония ...
Re: Чем искать банальную утечку
От: Mystic Украина http://mystic2000.newmail.ru
Дата: 10.04.15 08:36
Оценка:
Здравствуйте, кубик, Вы писали:

К>Подскажите чем можно найти такие ошибки копипейста:


На далее, как вчера, прогнало свой проект через cppcheck, и он нашел более запутанный случай утечки.
Re[2]: Чем искать банальную утечку
От: ArtDenis Россия  
Дата: 10.04.15 08:52
Оценка:
Здравствуйте, кубик, Вы писали:

К>А статичный анализатор для Visual studio на такое хотя бы обратит внимание? Если да, то какой порекомендуете?


Нет, тупо не видит. Но зато видит встроенный поиск утечек в рантайме:
Detected memory leaks!
Dumping objects ->
d:\c++\console\console.cpp(17) : {68} normal block at 0x009E73D0, 4 bytes long.
 Data: <    > CD CD CD CD 
Object dump complete.


PS: cppcheck видит сразу:
D:\C++\console\console.cpp(19): error: Memory leak: a


Это всё для кода
void* func1()
{
    return new int;
}

void* func2()
{
    return new int;
}


int main()
{
    void * a = func1();
    if (a)
    {
        void * a = func2();
    }
    delete a;
}
[ 🎯 Дартс-лига Уфы | 🌙 Программа для сложения астрофото ]
Re[2]: Чем искать банальную утечку
От: Кодт Россия  
Дата: 10.04.15 12:13
Оценка:
Здравствуйте, jazzer, Вы писали:

J>как насчет переписать на смарт-пойнтеры?

J>
J>std::unique_ptr<...> a{func1()};
J>


Вот специально на такие случаи — было бы очень круто иметь переменные с фантомными типами.
Что-то в таком роде:
unassigned<int> x, x0;

foo(x); // static assert failed: доступ к неинициализированной переменной

// собственно, только ради этого и разнесено объявление и инициализация
if(cond)
  x = bar();
else
  x = buz();

foo(x); // всё равно нельзя, ибо!

x = bar(); // runtime assert failed: повторная инициализация присваиванием (в дебаге придётся тащить булев флажок)

assigned<int> y0; // static assert failed: конструктор без параметров - т.е. не инициализировали
assigned<int> y00(x0); // runtime assert failed: x0 не инициализирован // булев флажок в unassigned<T> подсказывает
assigned<int> y(x), y2(buz());

foo(y); foo(y2);
foo(y00); // проверок не нужно, ибо они были сделаны ранее


Хотя, конечно, сложная ветвистая инициализация нынче делается на лямбдах
int x = [&]()->int {
  some local,vars;
  eval(local,vars);
  if(cond)
    return foo(local);
  else
    return bar(vars);
}();

И достаточно сделать обёртку assigned<T> без дефолтного конструктора. Хошь-нехошь, а инициализируешь.
Перекуём баги на фичи!
Re[3]: Чем искать банальную утечку
От: jazzer Россия Skype: enerjazzer
Дата: 10.04.15 12:36
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Хотя, конечно, сложная ветвистая инициализация нынче делается на лямбдах


вот именно
И код на С++ все больше становится похожа на JS
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[2]: Чем искать банальную утечку
От: flаt  
Дата: 10.04.15 15:27
Оценка:
Здравствуйте, кубик, Вы писали:

К>А статичный анализатор для Visual studio на такое хотя бы обратит внимание? Если да, то какой порекомендуете?

PVS хорош.
Re[4]: Чем искать банальную утечку
От: Кодт Россия  
Дата: 10.04.15 20:47
Оценка:
Здравствуйте, jazzer, Вы писали:

J>И код на С++ все больше становится похожа на JS


Не тот смайлик ты ставишь

А какой синтаксис красивый сделать для этого добра — загадка.
Перекуём баги на фичи!
Re[5]: Чем искать банальную утечку
От: BulatZiganshin  
Дата: 13.04.15 18:10
Оценка:
Здравствуйте, Кодт, Вы писали:

К>А какой синтаксис красивый сделать для этого добра — загадка.


чем haskell/coffee script не устраивает? слишком уж удобно? сравни

std::thread reading_thread ([&] {handle ("Reading_PROCESS", [&]{Reading_PROCESS();});});

и

reading_thread <- forkIO$ handle "Reading_PROCESS" Reading_PROCESS

а потом люди уверяют, что лямбды загромождаю код
Люди, я люблю вас! Будьте бдительны!!!
Отредактировано 13.04.2015 18:14 BulatZiganshin . Предыдущая версия .
Re[6]: Чем искать банальную утечку
От: Кодт Россия  
Дата: 14.04.15 10:28
Оценка:
Здравствуйте, BulatZiganshin, Вы писали:

BZ>чем haskell/coffee script не устраивает? слишком уж удобно?


Да практически тем же: зигзагообразным порядком чтения.
В коротких формулах удобно писать корнем вперёд
dest = summary( src1, src2, src3 )   -- сразу видно, куда что присваивается
dest = src1 `op` src2 `op` src3      -- а если объединяющая операция примитивная, то и все операнды перед глазами

А в длинных действиях, всё же, предпочтительнее обратная нотация, листьями вперёд
let
  f = foo
  b = bar
  u = buz
in summary f b u

Конвеерные стили того и другого — это
summary $ foo $ bar $ buz x y z
(x,y,z) |> buz |> bar |> foo |> summary


А когда эти два стиля смешиваются, получается адъ.
А смешиваются они из-за синтаксиса, в котором объявление переменной-приёмника должно предшествовать значению
x = (let ..... in .....)
x <- do { ..... }


Было БЫ симпатично, если БЫ была доступна и обратная нотация
runState xyz $ do
  foo
  bar
  buz
  return summary
==> x :: Int      --> опа, ввели переменную здесь
-- и только с этого места  она эксплуатируется


Ладно хаскелл, в нём вся рекурсия неявная, все let суть letrec.
А вот С++, в котором letrec переменных — штатные грабли, или ML, в котором let и letrec живут порознь и тоже могут довести до граблей — там-то позднее объявление пригодилось бы (как мне кажется).
int foo(int* x) { printf("%p",x); return 123; }
int bar(int* x) { printf("%d",*x); return 123; }
int buz(int* x) { *x = 456; return 123; }

int x = foo(&x); // это не страшный летрек
int y = bar(&y); // чтение до инициализации
int z = buz(&z); // запись до инициализации (для классов с конструктором это особенно весело)

let fact n = 123 (* заглушка *) in
let fact n = if n<1 then 1 else n * fact (n-1) (* ай, забыли let rec *) in
print_int (fact 5); (* 615, wtf?! *)
Перекуём баги на фичи!
Re[7]: Чем искать банальную утечку
От: BulatZiganshin  
Дата: 14.04.15 10:59
Оценка:
Здравствуйте, Кодт, Вы писали:

К>>>>А какой синтаксис красивый сделать для этого добра — загадка.


К>Было БЫ симпатично, если БЫ была доступна и обратная нотация


похоже, ты сам и ответил на свой вопрос?
Люди, я люблю вас! Будьте бдительны!!!
Re[8]: Чем искать банальную утечку
От: Кодт Россия  
Дата: 14.04.15 13:25
Оценка:
Здравствуйте, BulatZiganshin, Вы писали:

К>>>>>А какой синтаксис красивый сделать для этого добра — загадка.

К>>Было БЫ симпатично, если БЫ была доступна и обратная нотация

BZ>похоже, ты сам и ответил на свой вопрос?


Не ответил, а только помечтал.
Нужно же, чтобы синтаксис был непротиворечивый. А у нас есть и уровень пространства имён, и класса, и внутри шапки стейтментов if/for/while.
Фиг знает, что там повылазит.

Хотя, может быть, пропозал для C++1xz написать. Пускай у Отцов Основателей башка болит.
// префиксное определение
auto x = expression();
some x = {c-style};
some x {c++14-style};

// суффиксное
expression() => auto x;
{ expression(), expression(), expression() } => some y;

чтоб там не полезли неоднозначности, чтоб не показалось, будто expression() или {expression()} — это что-то иное, нежели инициализация определения.

А так,
if(
  []()->auto{ // чёрт с ним, пусть будет обычная лямбда с префиксной аннотацией типа
    foo();
    bar();
    buz();
    return new XZ();
  }() // и с обычным для лямбды подвалом
  => auto xz
)
{ xz->gogogo(); }


Опять же, какой токен использовать для присваивания? -> наверно, нельзя: для левого операнда это оператор, в отличие от контекста "шапка функции или лямбды". Что-то новое, не являющееся оператором? Как, например, =>

А как быть с множественным определением?
for(int x=1, y=2, z=3; ......)
for(1=>int x, ?!!! после запятой, казалось бы, ещё один int; а после ';' уже выражение условия цикла


Кроме того: если [&]()->auto{......}()=>auto x становится идиомой, (а auto x = [&]()->auto{......}() уже сейчас идиоматично), то, наверно, стоит всё это крючкотворство повыкидывать?
auto x = do{.....};
do{....} => auto x;

Ведь и так понятно, что эта лямбда ничего не защёлкивает, а просто немедленно выполняется, и всё.
Перекуём баги на фичи!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.