В языке С нет операторов new и delete, работающих с объектами. Для использования свободной памяти в нем используются функции, работающие с памятью. Наиболее важные функции определены в стандартном заголовочном файле общих утилит .

void* malloc(size_t sz); /* выделить sz байтов */

void free(void* p);      /* освободить область памяти, на которую

                            ссылается указатель p */

void* calloc(size_t n, size_t sz); /* выделить n*sz байтов,

                                      инициализировав их нулями */

void* realloc(void* p, size_t sz); /* вновь выделить sz байтов

                                      в памяти, на которую ссылается

                                      указатель p*/

Тип typedef size_t — это тип без знака, также определенный в заголовочном файле .

  Почему функция malloc() возвращает указатель void*? Потому что она не имеет информации о том, объект какого типа вы хотите разместить в памяти. Инициализация — это ваша проблема. Рассмотрим пример.

struct Pair {

  const char* p;

  int val;

};

struct Pair p2 = {"apple",78};

struct Pair* pp = (struct Pair*) malloc(sizeof(Pair)); /* выделить память */

pp–>p = "pear"; /* инициализировать */

pp–>val = 42;

Теперь мы не можем написать инструкцию

*pp = {"pear", 42}; /* ошибка: не C и не C++98 */

ни в программе на языке C, ни в программе на языке C++. Однако в языке С++ мы могли бы определить конструктор для структуры Pair и написать инструкцию Pair* pp = new Pair("pear", 42);

В языке C (но не в языке C++; см. раздел 27.3.4) перед вызовом функции malloc() можно не указывать приведение типа, но мы не рекомендуем это делать.

int* p = malloc(sizeof(int)*n); /* избегайте этого */

Игнорирование приведения довольно часто встречается в программах, потому что это экономит время и позволяет выявить редкую ошибку, когда программист забывает включить в текст программы заголовочный файл перед использованием функции malloc(). Однако при этом исчезает и визуальный маркер, свидетельствующий о том, что размер памяти подсчитан неправильно.

p = malloc(sizeof(char)*m); /* вероятно, ошибка — нет места для m целых */

  Не используйте функции malloc()/free() в программах, написанных на языке C++; операторы new/delete не требуют приведения типа, выполняют инициализацию (вызывая конструкторы) и очищают память (вызывая деструкторы), сообщают об ошибках, связанных с распределением памяти (с помощью исключений), и просто работают быстрее. Не удаляйте объект, размещенный в памяти с помощью функции malloc(), выполняя оператор delete, и не удаляйте объект, созданный с помощью оператора new, вызывая функцию free(). Рассмотрим пример.

int* p = new int[200];

// ...

free(p); // ошибка

X* q = (X*)malloc(n*sizeof(X));

// ...

delete q; // error

Этот код может оказаться вполне работоспособным, но он не является переносимым. Более того, для объектов, имеющих конструкторы и деструкторы, смешение стилей языков C и C++ при управлении свободной памятью может привести к катастрофе. Для расширения буферов обычно используется функция realloc().

int max = 1000;

int count = 0;

int c;

char* p = (char*)malloc(max);

while ((c=getchar())!=EOF) { /* чтение: игнорируются символы

                                в конце файла */

  if (count==max–1) {        /* необходимо расширить буфер */

    max += max;              /* удвоить размер буфера */

    p = (char*)realloc(p,max);

    if (p==0) quit();

  }

  p[count++] = c;

}

Объяснения операторов ввода в языке С приведены в разделах 27.6.2 и Б.10.2.

  Функция realloc() может выделить память на прежнем участке, а может и перенести его содержимое во вновь выделенную область памяти. Даже не думайте применять функцию realloc() к области памяти, выделенной с помощью оператора new.

Используя стандартную библиотеку языка C++, этот код можно переписать примерно так:

vector buf;

char c;

while (cin.get(c)) buf.push_back(c);

Перейти на страницу:
Нет соединения с сервером, попробуйте зайти чуть позже