1. Pascal / Говнокод #9430

    +88

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    var A:array of record
      Foo: integer;
    end;
    
    function NewNode: integer;
    begin
      SetLength(A, Length(A)+1);
      Result := High(A);
      // возвращаем не указатель на последний элемент,
      // а номер последнего элемента, потому что массив динамический и указатели нестабильны
    end;
    
    procedure DoSmth(var i: integer);
    var
      n1,n2: integer;
    begin
      n1 := NewNode;
      n2 := NewNode;
      // дальше что-то проделывааем над A[n1] и A[n2]
      i := A[n1].Foo + A[n2].Foo;
    end;
    
    var
      NewIndex: integer;
    begin
      NewIndex := NewNode;
      DoSmth(A[NewIndex].Foo);
    end.

    Угадайте, почему это не будет работать и приведёт к порче памяти.

    Запостил: TarasB, 15 Февраля 2012

    Комментарии (20) RSS

    • В 27 строке в процедуру DoSmth неявно передается указатель на A[0].Foo, а уже в самой процедуре после строк 17 и 18 массив реаллоцируется и указатель становится недействительным. Не?
      Ответить
      • Да.
        Проблема в том, что у меня может быть три var-параметра.
        В итоге, чтобы это побороть, я вместо процедуры сделал функцию, возвращающую структуру из 3 членов. В языке с хреновой поддержкой кортежей это вылилось в целый убитый день.
        Хорошо ещё, что дельфа вычисляет адрес места, куда возвращать значение, уже после выполнения функции.
        Ответить
    • > Угадайте, почему это не будет работать и приведёт к порче памяти.

      ну да ты уже описал, но мне было почти очевидно: у меня много опыта работы с итераторами std::vector'а :)

      с другой стороны. меня как-то напрягает тот SetLength(). я как-то никогда не задумывался как именно он работает. но если он сделан глупо как и все остальное в пасцале, то с легкостью может привести к квадратичной сложности функции NewNode().
      Ответить
      • > я как-то никогда не задумывался как именно он работает. но если он сделан глупо как и все остальное в пасцале

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

          Если бы ты просто сказал что я ламер, это было бы ОК: мой 7+ лет опыт професиональной работы с Турбо/Борланд Паскалем/Дельфой на самом деле уже скоро будет как 10 лет позади.

          Но следующим за этим списком ты показывашь что ты сам ламер который не только С++ не знает толком, а просто лох невпечатывающий что System.pas не богами писан и он физически не может работать лучше/быстрее чем современные алгоритмы. Да и даже те же современные алгоритмы дай в руке обезьяне...
          Ответить
          • Слушай, ты, system.pas хоть и не богами писан, но многие вещи в нём сделаны разумно а многие глупо, да, но в целом всё достаточно адекватно. Я не говорю, что он идеал, но твоё "всё сделано глупо" и выдаёт в тебе ламера и лоха, ага.

            И нехуй тут мне ставить минусики, а оппоненту плюсики, раз вы тупые кретобляди, нихуя не знающие, кроме "пасцаль сакс", то идите-ка нахуй, и сюда со своими крестоблядскими оценками блядь не лезьте.

            Потому что меня заебало доказывать крестоблядям, что паскальный case компилируется в двоичное дерево или сразу переход по значение, потому что они уверены в том, что case компилируется в цепочку if, ведь им кулкацкер вася в 9 классе так сказал.
            Познания крестоблядей о паскале и до сих пор находятся на уровне 9го класса, что мы и видим в данной беседе.
            Ответить
    • > Угадайте, почему это не будет работать и приведёт к порче памяти.
      Тарас в погоне за Урсусом?
      Ответить
      • > в целом получилось ещё смешнее, чем я ожидал
        Ответить
    • Тарас гонит на паскаль? Это что-то новенькое... А что там с динамическими массивами в Ада?
      Ответить
      • На Паскаль я не гоню, потому что вектор - он и в Африке вектор, со всеми его особенностями.
        И в Аде вектора такие же и сделать такой же прикол там никто не мешает.
        Ответить
    • почему нельзя function DoSmth(): integer; ?
      ну или там record возвращать
      Ответить
      • Потому что возвращать record в языке с хреновыми кортежами неудобно. var удобнее.
        Но в конечном итоге я был вынужден так и сделать:
        [quote]
        Да.
        Проблема в том, что у меня может быть три var-параметра.
        В итоге, чтобы это побороть, я вместо процедуры сделал функцию, возвращающую структуру из 3 членов. В языке с хреновой поддержкой кортежей это вылилось в целый убитый день.
        Хорошо ещё, что дельфа вычисляет адрес места, куда возвращать значение, уже после выполнения функции.
        [/quote]
        http://govnokod.ru/9430#comment130379
        Ответить
        • А всего лишь нужно знать разницу между передачей по ссылке и по значению.

          Почему бы не написать
          DoSmth(tmp);
          A[NewIndex].Foo := tmp;
          ?

          Параметры добавить по потребности. И никаких структур.
          Ответить
          • Ну потому, что после взятия NewIndex я мог что-то ещё сделать со структурой и DoSmth учитывает старое значение структуры.
            То есть придётся писать
            tmp := A[NewIndex];
            DoSmth(tmp);
            A[NewIndex].Foo := tmp;

            В общем, радости мало.
            Пока что у меня как-то так:
            with DoSmth(A[N1]) do begin
              if not Success then Exit;
              A[N1] := Res;
            end;
            Ответить
            • if DoSmth(A[N1], Res) then A[N1] := Res;

              Чем хуже? Писанины меньше. Нормальный сишный код (раньше в Си нельзя было из функций возвращать структуры).
              Ответить
              • Тоже вариант. Только переменную заводить блин надо.
                Ответить
    • Что такое array of record? Это не Паскаль.
      Ответить
      • Тарас - читер, пользуется неправославными расширениями.
        Ответить
      • http://maps.google.ru/maps?hl=ru&q=38.480501,+22.490052
        Ответить
    • Я парень, 24 года. Хочу отсосать у кавказца. Пиши желательно с фото на [email protected], вышлю в ответ
      Ответить

    Добавить комментарий