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
char c;
while (cin.get(c)) buf.push_back(c);
Более подробное обсуждение стратегий ввода и распределения памяти можно найти в статье “Learning Standard C++ as a New Language” (см. список библиографических ссылок в конце раздела 27.1).
27.5. Строки в стиле языка С
Строка в языке C (в литературе, посвященной языку С++, ее часто называют
char* p = "asdf";
char s[ ] = "asdf";
В языке C нет функций-членов, невозможно перегружать функции и нельзя определить оператор (такой как ==
) для структур. Вследствие этого для манипулирования строками в стиле языка С необходим набор специальных функций (не членов класса). В стандартных библиотеках языков C и C++ такие функции определены в заголовочном файле
.
size_t strlen(const char* s); /* определяет количество символов */
char* strcat(char* s1, const char* s2); /* копирует s2 в конец s1 */
int strcmp(const char* s1, const char* s2); /* лексикографическое
сравнение */
char* strcpy(char* s1,const char* s2); /* копирует s2 в s1 */
char* strchr(const char *s, int c); /* копирует c в s */
char* strstr(const char *s1, const char *s2); /* находит s2 в s1 */
char* strncpy(char*, const char*, size_t n); /* сравнивает n
символов */
char* strncat(char*, const char, size_t n); /* strcat с n
символами */
int strncmp(const char*, const char*, size_t n); /* strcmp с n
символами */
Это не полный список функций для работы со строками, но он содержит самые полезные и широко используемые функции. Кратко проиллюстрируем их применение.
==
) сравнивает значения указателей; стандартная библиотечная функция strcmp
сравнивает значения C-строк.
const char* s1 = "asdf";
const char* s2 = "asdf";
if (s1==s2) { /* ссылаются ли указатели s1 и s2 на один и тот же
массив? */
/* (обычно это нежелательно) */
}