В программе — нигде.
Да и вообще у Вас там выход за пределы выделенной памяти
int len = strlen(s);
st.str = new char[len]; //Выделили память под len символов
strcpy(st.str, s); //Скопировали в приемник len символов + завершающий 0
Память, выделенная при помощи new, освобождается только при помощи delete или после завершения программы.
Юрий
Правильно, porshe! Применение new должно сопровождаться вызовом delete. Повторю вопрос.
ВОПРОС: Где в данной программе нужно вызвать операцию delete?
(Выход за пределы массива исправлен)
#include <iostream>
#include <cstring>
struct stringy{
char * str;
int ct;
};
void set(stringy & st, char * s);
void show(const stringy & st, int n = 1);
void show(const char * test, int n = 1);
int main()
{
stringy beany;
char testing[] = "Reality isn't what it used to be.";
set(beany, testing);
show(beany);
show(beany, 2);
testing[0] = 'D';
testing[1] = 'u';
show(testing);
show(testing, 3);
show("Done!");
return 0;
}
void set(stringy & st, char * s)
{
const int len = strlen(s);
st.str = new char[len + 1];
strcpy(st.str, s);
st.ct = len;
}
void show(const stringy & st, int n)
{
while(n--)
std::cout << st.str << std::endl;
}
void show(const char * test, int n)
{
while(n--)
std::cout << test << std::endl;
}
А я даже не знал, что это было задание, я думал это был вопрос :)
Где в данной программе нужно вызвать операцию delete?
Вообще, её здесь негде применять, дабы не потерять значение beany. Но уж если сильно хочется, то можно создать функцию _free(), которая освободит память, и присвоит beany.str = NULL.
P.S.: А почему бы не сделать класс? Будет ведь удобнее, и освобождением будет заниматься деструктор.
(0) В исходном варианте кода память освобождается только при завершении программы. Для того, что бы освободить память в программе, перед return 0 надо вставить оператор delete [] beany.str;. Но это не очень красивый вариант.
(1) Захват, перераспределение и освобождение ресурсов должно происходить на одном уровне абстракции. Это [должно быть!] общеизвестное правило. Если уровень абстракции функции, как в данном случае, то вариант от Croessmah как раз удовлетворяет этому правилу. Если уровень абстракции класс, то работа с ресурсами должна происходить на уровне методов класса.
(2) Вариант от Croessmah фактически реализует абстракцию на уровне класса. void init(stringy & st ) — конструктор, void release(stringy & st ) — деструктор, void set(stringy & st, char * s) — метод-сеттер или оператор присваивания, void show(const stringy & st, int n) — почти метод-геттер. Конечно, что бы привести этот код к виду нормального класса, требуется серьёзная доработка (для того, что бы во всех ситуациях класс (экземпляр класса) работал ожидаемым образом.
Кстати, хорошая тема для новой «разминки для мозгов»: аккуратно написать класс, реализующий строку со счётчиком (или «строка в стиле Pascal») без использования STL и других библиотек. Примечание: строка со счётчиком НЕ завершается '\0'.
Croessmah, почему всё так пессимистично? Тема вполне исчерпаемая, если не усложнять себе задачу абсолютной переносимостью кода в сочетании с абсолютной эффективностью, поддержкой многобайтовых кодировок и неограниченным объёмом строки.
В данном случае, смысл «разминки» заключался бы в аккуратном написании класса с динамическим захватом и освобождением ресурсов (памяти) и с минимальной функциональностью. Ключевое слово «аккуратно». Задачка достаточно простая, но есть подводные камни. В плане повышения собственного скилла — полезно.
Внимание! Это довольно старый топик, посты в него не попадут в новые, и их никто не увидит. Пишите пост, если хотите просто дополнить топик, а чтобы задать новый вопрос — начните новый.
Доброго времени суток всем!!!
Имею вот такой вопрос. Вот код
ВОПРОС: Где освобождается память, выделенная в функции
void set(stringy & st, char * s)?В программе — нигде.
Да и вообще у Вас там выход за пределы выделенной памяти
Но память то выделена при помощи new?
Память, выделенная при помощи
new, освобождается только при помощиdeleteили после завершения программы.Правильно, porshe! Применение
newдолжно сопровождаться вызовомdelete. Повторю вопрос.ВОПРОС: Где в данной программе нужно вызвать операцию delete?
(Выход за пределы массива исправлен)
А я даже не знал, что это было задание, я думал это был вопрос :)
Вообще, её здесь негде применять, дабы не потерять значение
beany. Но уж если сильно хочется, то можно создать функцию_free(), которая освободит память, и присвоитbeany.str = NULL.P.S.: А почему бы не сделать класс? Будет ведь удобнее, и освобождением будет заниматься деструктор.
Чёрт, понял в чём тут фишка.
Освобождать память нужно в начале функции
set, что бы избежать утечки памяти.То есть как то так:
При условии, что пустая
st.str = NULL( можно задать в конструкторе, например ).можно без if.
То есть, если попытаться освободить память по адресу
0, то ничего не произойдёт?Ничего.
Ребята, программа не компилится ???
Да и не логично удалять в функции
void set(stringy & st, char * s)память при помощиdeleteперед тем как функция выделяет память при помощиnew.логично.
А как ещё избежать утечки памяти?
делать нормальный класс. А еще лучше пользоваться готовым :)
я про это уже писал выше :)
Резюмируя вышесказанное...
(0) В исходном варианте кода память освобождается только при завершении программы. Для того, что бы освободить память в программе, перед
return 0надо вставить операторdelete [] beany.str;. Но это не очень красивый вариант.(1) Захват, перераспределение и освобождение ресурсов должно происходить на одном уровне абстракции. Это [должно быть!] общеизвестное правило. Если уровень абстракции функции, как в данном случае, то вариант от Croessmah как раз удовлетворяет этому правилу. Если уровень абстракции класс, то работа с ресурсами должна происходить на уровне методов класса.
(2) Вариант от Croessmah фактически реализует абстракцию на уровне класса.
void init(stringy & st )— конструктор,void release(stringy & st )— деструктор,void set(stringy & st, char * s)— метод-сеттер или оператор присваивания,void show(const stringy & st, int n)— почти метод-геттер. Конечно, что бы привести этот код к виду нормального класса, требуется серьёзная доработка (для того, что бы во всех ситуациях класс (экземпляр класса) работал ожидаемым образом.Кстати, хорошая тема для новой «разминки для мозгов»: аккуратно написать класс, реализующий строку со счётчиком (или «строка в стиле Pascal») без использования STL и других библиотек. Примечание: строка со счётчиком НЕ завершается '\0'.
увы, эта тема бесконечна и не имеет решения :)
Череп, а подробнее, что за строка со счетчиком?
И если есть время посмотри мой первый класс :)
Croessmah, почему всё так пессимистично? Тема вполне исчерпаемая, если не усложнять себе задачу абсолютной переносимостью кода в сочетании с абсолютной эффективностью, поддержкой многобайтовых кодировок и неограниченным объёмом строки.
В данном случае, смысл «разминки» заключался бы в аккуратном написании класса с динамическим захватом и освобождением ресурсов (памяти) и с минимальной функциональностью. Ключевое слово «аккуратно». Задачка достаточно простая, но есть подводные камни. В плане повышения собственного скилла — полезно.