char * data = «abc»; бесплатно ((void *) данные); Почему void * преобразование? Это необходимо?

0

Существует строка стиля C, и мне нужно освободить память. Я видел следующий пример кода, но смутился о том, почему (void*) есть.

char *data = "abc";
free( (void*)data );

Всего два вопроса:

  1. Почему бы не просто free(data)?

  2. Является ли (void*) преобразование обязательным?

Большое спасибо.

  • 5
    Это не правильно в любом случае. Не освобождайте фиксированные литералы.
  • 2
    (и нет, конвертация не нужна в бесплатной части)
Теги:

4 ответа

6
Лучший ответ

Нет, это не обязательно; звонок free() ошибочен, и вы не можете этого сделать.

Бросок - это огромный мигающий, подпрыгивающий и кричащий предупреждающий флаг, с которым запутался программист.

Это неопределенное поведение, чтобы передать указатель, не возвращенный предыдущим вызовом malloc() или одному из его друзей, в free(). Литье - это наименьшая проблема здесь.

Вы никогда не сможете "освободить" память, используемую строковым литералом, поскольку эта память никогда не выделяется каким-то образом, что программа контролирует. Это не в куче, а куча - это то, где обычно происходит распределение/освобождение динамической памяти. Ваше намерение неверно.

Все, что вы можете сделать, это установить указатель на NULL:

data = NULL;

это никоим образом не "освободит" память, используемую за кулисами, для хранения символьных данных "abc" хотя, но это прекрасно.

3

Является ошибкой для вызова free() поскольку не выделяется с использованием (m/c/re)alloc.

Как указал Йенс Густедт, приведение требуется только при передаче указателя const потому что free() принимает void *, а не const void *:

const int *x = malloc(sizeof(int));

free((void *)x);

Без броска вы получаете:

demo.c:8:5: warning: passing argument 1 of ‘free discards ‘const qualifier from pointer target type [enabled by default] In file included from demo.c:2:0: /usr/include/stdlib.h:488:13: note: expected ‘void * but argument is of type ‘const int *
  • 1
    Это неоднозначно. Это не нужно отбрасывать , поскольку она не была выделена динамически?
  • 1
    Никогда не нужно, это не правда, к сожалению. Если у вас есть указатель на const , многие компиляторы жалуются.
Показать ещё 3 комментария
0

Бросок не нужен. В C, void* неявно конвертируется в и из других типов указателей. free ожидает void*, поэтому для другого типа указателя не требуется никакого перевода.

(Конечно, как уже указывалось, код явно проблематичен вообще, поэтому не читайте его слишком много.)

0

Итак, ваша предпосылка здесь неверна, вам не нужно вообще бесплатно "ваши данные", она, скорее всего, вызовет сбой, если вы это сделаете. Вы должны только звонить free для данных, полученных из malloc, и "abc" не является одним из них.

Во-вторых, если вы используете C, вам следует:

char *data = malloc(4);
strcpy(data, "abc");
...
free(data);

В C++ мы также не можем преобразовать void * [возвращаемое значение из malloc ] в char *, поэтому вам понадобится char *data = (char *) malloc(4); , но free(data) должны по-прежнему работать. Некоторые компиляторы могут выдавать предупреждения для этого, а стандартная MISRA, например, не разрешает ЛЮБОЕ автоматическое преобразование типов C, поэтому явные приведения здесь НЕОБХОДИМО [не потому, что язык говорит так, а потому, что стандарт MISRA делает, и есть "проверка программного обеспечения", которое считывает исходный код для проверки такого рода критериев, выполняется].

Конечно, в "свежих" [1] C++ мы не должны использовать malloc или free, но new и delete:

char *data = new char[4];
strcpy(data, "abc");
....
delete [] data;

[1] Как в "коде, написанном как C++ с нуля".

Ещё вопросы

Сообщество Overcoder
Наверх
Меню