Подтвердить что ты не робот

Можно ли освободить 'void *'?

struct foo
{
    int a;
    int b;
};

void* p = (void*)malloc(sizeof(struct foo));
((foo*)p)->a;//do something.
free(p);//Is this safe?
4b9b3361

Ответ 1

Да.

malloc возвращает void *, а free принимает void *, поэтому некоторые ваши приведения бессмысленны, и вы всегда освобождаете void *, даже если вы начинаете с какого-то другого указателя.

Ответ 2

Да, это безопасно. При распределении памяти библиотека времени выполнения отслеживает размер каждого распределения. Когда вы вызываете free(), он просматривает адрес, и если он находит выделение для этого адреса, освобождается правильный объем памяти (блок, который был выделен по этому адресу).

Ответ 3

Да - free принимает указатель на void, поэтому, когда вы его вызываете, указатель (неявно) отбрасывается на указатель на пустоту в любом случае.

Остальная часть вашего кода не совсем безопасна:

void* p = (void*)malloc(sizeof(foo));

Вы не должны отбрасывать возврат из malloc (в C). Это может скрыть ошибку, забыв о #include <stdlib.h>

Ответ 4

Да. Прототип функции для free равен:

void free(void *ptr);

Ответ 5

в C это совершенно безопасно, потому что нет деструкторов для вызова.

система памяти отслеживает размер распределения.

в С++ вы должны удалить тот же тип, что и новый, в том числе с помощью оператора delete [] для удаления новых массивов.

это только для того, чтобы вызывать деструкторы.

Ответ 6

Возможно, он не чувствует себя в безопасности из-за того, что магия происходит за кулисами. Среда выполнения C и/или сама ОС активно отслеживают память, возвращаемую malloc, включая ее размер и местоположение. Смотрите, хотя кажется, что вы передаете беззнаковый указатель обратно в free(), вы фактически передаете ссылку на объект, который активно отслеживает менеджер памяти.

Ответ 7

да, это безопасно.

Ответ 8

Да, но обычно это признак плохого дизайна. malloc() обычно используется для выделения буферов (больших массивов одного и того же примитивного типа) или объектов (структуры с инициализированными полями). В обоих случаях malloc и free должны соответствовать таким образом

  unsigned char *rgba_buffer = malloc(width * hieght * 4);
  /* use the buffer here */
  free(rgba_buffer);

  BITSTREAM *bs = bitstream("bitfile.boin");
  /* use the bitstream here */
  destroy_bitstream(bs);

  typedef struct
  {
     FILE *fp;
     unsigned char ch;
     int index;
  } BITSTREAM;


  BITSTREAM *bitstream(const char *filename)
  {
      BITSTREAM *bs = malloc(sizeof(BITSTREAM));
      bs->fp = fopen(filename "rb");
      /* etc */
      return bs;
  }

  void destroybitstream(BITSTREAM *bs)
  {
     if(bs)
     {
        if(bs->fp)
          fclose(bs->fp);
        free(bs);
     }
  }

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

Современный С++ ужесточает все это с помощью уникальных указателей, которые "владеют" объектом. Хотя вы можете иметь уникальный указатель на пустоту, это было бы очень редко.