Free()

Тема в разделе "Общие вопросы по С и С++", создана пользователем Normann, 22 авг 2007.

  1. Normann

    Normann Well-Known Member

    Регистрация:
    9 авг 2007
    Сообщения:
    168
    Симпатии:
    2
    Вопрос таков, если я займу блок памяти например вот таким макаром:

    int *nVec = (int*)malloc(10 * sizeof(int));

    А потом сделаю вот так:

    nVec+=5;

    то каков будет потом смысл и результат вот этого?:

    free(nVec);
     
  2. Kmet

    Kmet Well-Known Member

    Регистрация:
    25 май 2006
    Сообщения:
    1.017
    Симпатии:
    1
    ничего хорешего, зависит от реализации
     
  3. Herbert

    Herbert Гость

    Вернуть память "наполовину" (с пятого элемента) наверное не получится.

    У меня ошибка вылетает (Microsoft Visual C++ 6.0)
     
  4. Normann

    Normann Well-Known Member

    Регистрация:
    9 авг 2007
    Сообщения:
    168
    Симпатии:
    2
    У меня в Turbo C++3.0 выполняется спокойно, но при использовании calloc вместо malloc вылитает совсем при попытке освобождения с неверным указателем, а в VC6 ругается на все.
    Кто знает откуда free знает сколько нужно освободить памяти? Он хранит где нибудь такую информацию?
     
  5. Herbert

    Herbert Гость

    Как я понял тут такая фигня:
    free не знает о количестве памяти которую надо освободить. Он освобождает сразу ВСЮ память, которую указатель nVec держит (в данном случае 40 байт - по 4 на каждую int). Указатель конечно "знает" сколько он держит, но получить это значение от него нельзя. Это точно (я где-то такую тему уже видел, там про динамические массивы речь шла). То есть имея указатель nVec ты не можешь от него получить инфу о количестве захваченной им памяти. Эту цифру 40 нужно с самого начала запомнить и бережно хранить (как и сам указатель), иначе не будешь знать сколько значений int под nVec запихнуть можно. Указатель тебе этого не скажет.
    Выполнив строку nVec+=5; ты уже безвозвратно потерял возможность вернуть эти 40 байт т.к. "убил" указатель который "знал" о количестве захваченной памяти и адресе ее начала.

    Это подтверждает что все действительно
    , но правильно работать не будет нигде. (Мне так кажется. может кто и опровергнет)
     
  6. Normann

    Normann Well-Known Member

    Регистрация:
    9 авг 2007
    Сообщения:
    168
    Симпатии:
    2
    Где про такие вещи можно прочитать не знаешь? Хотя бы на английском :blink:
     
  7. Kmet

    Kmet Well-Known Member

    Регистрация:
    25 май 2006
    Сообщения:
    1.017
    Симпатии:
    1
    <!--QuoteBegin-Herbert+23:08:2007, 22:47 -->
    <span class="vbquote">(Herbert @ 23:08:2007, 22:47 )</span><!--QuoteEBegin-->Как я понял тут такая фигня:
    free не знает о количестве памяти которую надо освободить. Он освобождает сразу ВСЮ память, которую указатель nVec держит (в данном случае 40 байт - по 4 на каждую int). Указатель конечно "знает" сколько он держит, но получить это значение от него нельзя. Это точно (я где-то такую тему уже видел, там про динамические массивы речь шла). То есть имея указатель nVec ты не можешь от него получить инфу о количестве захваченной им памяти. Эту цифру 40 нужно с самого начала запомнить и бережно хранить (как и сам указатель), иначе не будешь знать сколько значений int под nVec запихнуть можно. Указатель тебе этого не скажет.
    Выполнив строку nVec+=5; ты уже безвозвратно потерял возможность вернуть эти 40 байт т.к. "убил" указатель который "знал" о количестве захваченной памяти и адресе ее начала.
    [snapback]76216" rel="nofollow" target="_blank[/snapback]​
    [/quote]

    указатель ничего не держит.. он УКАЗЫВАЕТ.
    осмелю предположить если сделать

    Код (Text):
    int *nVec = (int*)malloc(10 * sizeof(int));
    nVec+=5;
    nVec-=5;
    free(nVec);
    все пройдет успешно.

    зависит от реализации, если не ошибаюь МС хранит в четырех байтах перед выделенным блоком.

    Зачем? За использование таких нюансов комптляторов -- руки в косяк.
     
  8. mms

    mms Гость

    <!--QuoteBegin-Herbert+23:08:2007, 22:47 -->
    <span class="vbquote">(Herbert @ 23:08:2007, 22:47 )</span><!--QuoteEBegin-->free не знает о количестве памяти которую надо освободить. Он освобождает сразу ВСЮ память, которую указатель nVec держит (в данном случае 40 байт - по 4 на каждую int). Указатель конечно "знает" сколько он держит, но получить это значение от него нельзя. Это точно (я где-то такую тему уже видел, там про динамические массивы речь шла). То есть имея указатель nVec ты не можешь от него получить инфу о количестве захваченной им памяти. Эту цифру 40 нужно с самого начала запомнить и бережно хранить (как и сам указатель), иначе не будешь знать сколько значений int под nVec запихнуть можно. Указатель тебе этого не скажет.
    Выполнив строку nVec+=5; ты уже безвозвратно потерял возможность вернуть эти 40 байт т.к. "убил" указатель который "знал" о количестве захваченной памяти и адресе ее начала.
    [snapback]76216" rel="nofollow" target="_blank[/snapback]​
    [/quote]

    Че за бред? Что значит указатель "знал"? :), И что значит "Выполнив строку nVec+=5; ты уже безвозвратно потерял возможность вернуть эти 40 байт"? ;) Вообщем фигню порите.
     
  9. North

    North Гость

    2 Normann
    сие есть undefined behavior (UB), что с ихнего на наш переводится как неопределенное поведение.
    Типично можно предположить повреждение структуры данных распределителя памяти.
    Те, если ты выполнишь данный код программа может сделать все что угодно:
    - вести себя корректно (это лишь частный случай UB)
    - падать на последней строчке
    - показывать тебе синий экран
    - или форматировать тебе жесткий диск :eek:
    поведение не определено. Если даже у тебя сейчас все работает как надо, не факт что тот же exe-шник будет так же выполняться скажем на другой версии Windows.

    Смысл в таком коде существует только в рамках исследования поведения конкретного компилятора и учебы на ошибках.

    ПОЖАЛУЙСТА НЕ ПИШИ ТАКОЙ КОД :)
     
  10. Normann

    Normann Well-Known Member

    Регистрация:
    9 авг 2007
    Сообщения:
    168
    Симпатии:
    2
    <!--QuoteBegin-North+24:08:2007, 19:46 -->
    <span class="vbquote">(North @ 24:08:2007, 19:46 )</span><!--QuoteEBegin-->Типично можно предположить повреждение структуры данных распределителя памяти.
    [snapback]76316" rel="nofollow" target="_blank[/snapback]​
    [/quote]
    Кто такой распределитель памяти? Я хочу с ним познакомиться. И где тусуется эта структура памяти, телефончик ее не дадите? :eek:
     
  11. European

    Регистрация:
    4 сен 2006
    Сообщения:
    2.580
    Симпатии:
    0
    <!--QuoteBegin-Normann+24:08:2007, 22:03 -->
    <span class="vbquote">(Normann @ 24:08:2007, 22:03 )</span><!--QuoteEBegin-->Кто такой распределитель памяти?
    [snapback]76323" rel="nofollow" target="_blank[/snapback]​
    [/quote]
    У кучи спроси
     
  12. Normann

    Normann Well-Known Member

    Регистрация:
    9 авг 2007
    Сообщения:
    168
    Симпатии:
    2
    <!--QuoteBegin-European+24:08:2007, 23:26 -->
    <span class="vbquote">(European @ 24:08:2007, 23:26 )</span><!--QuoteEBegin-->У кучи спроси
    [snapback]76324" rel="nofollow" target="_blank[/snapback]​
    [/quote]
    Я ней плохо знаком, может познакомите.
     
  13. Normann

    Normann Well-Known Member

    Регистрация:
    9 авг 2007
    Сообщения:
    168
    Симпатии:
    2

Поделиться этой страницей