Некорректное завершение программы!?
// using new to get memory for strings
#include <iostream>
#include <cstring> //for strcpy(), etc
#include <Cctype>
using namespace std;
////////////////////////////////////////////////////////////////
class String //user-defined string type
{
private:
char* str; //pointer to string
public:
String(char* s) //constructor, one arg
{
int length = strlen(s); //length of string argument
str = new char[length+1]; //get memory
strcpy(str, s); //copy argument to it
}
~String() //destructor
{
cout << "\nDeleting str\n";
delete[] str; //release memory
}
void display() //display the String
{
cout << str << endl;
}
void upit();
};
//--------------------------------------------------------------
void String::upit()
{
while(*str)
{
putchar (toupper(*(str++)));
}
}
////////////////////////////////////////////////////////////////
int main()
{ //uses 1-arg constructor
String s1 = "Who knows nothing doubts nothing.";
cout << "s1="; //display string
s1.display();
s1.upit();
return 0;
}
Если закомментировать деструктор, тогда все ОК!
// member function converts String objects to upper case
#include <iostream>
#include <cstring> //for strcpy(), etc
#include <cctype> //for toupper()
using namespace std;
////////////////////////////////////////////////////////////////
class String //user-defined string type
{
private:
char* str; //pointer to string
public:
String(char* s) //constructor, one arg
{
int length = strlen(s); //length of string argument
str = new char[length+1]; //get memory
strcpy(str, s); //copy argument to it
}
~String() //destructor
{ delete str; }
void display() //display the String
{ cout << str; }
void upit(); //uppercase the String
};
//--------------------------------------------------------------
void String::upit() //uppercase each character
{
char* ptrch = str; //pointer to this string
while( *ptrch ) //until null,
{
*ptrch = toupper(*ptrch); //uppercase each character
ptrch++; //move to next character
}
}
////////////////////////////////////////////////////////////////
int main()
{
String s1 = "He who laughs last laughs best.";
cout << "\ns1="; //display string
s1.display();
s1.upit(); //uppercase string
cout << "\ns1="; //display string
s1.display();
cout << endl;
return 0;
}
Вопросы:
1. Почему 1й вариант работает неправильно?
2. toupper как-то работает с 'cout'?
На '\0' (последний нулевой символ массива)?
Получается что деструктор не удаляет str?
После этого все заработало:
{
while(*str)
{
putchar (toupper(*(str++)));
}
str=0;
}
Отсюда вытекают 2 вопроса:
1. Почему в первом случае:
{
cout << "\nDeleting str\n";
delete[] str; //release memory
}
В втором:
{ delete str; }
В книге я читал чтобы удалить массив нужно после delete поставить []...
2. Для чего была сделана ссылка на ссылку?
Для того чтобы не обнулять str?
Получается что деструктор не удаляет str?
да
{
while(*str)
{
putchar (toupper(*(str++)));
}
str=0;
}
Не заработало. Память не освобождается. Указатель не вернулся к исходной точке.
Для того чтобы не обнулять str?
Не ссылка на ссылку, а разименовавание указателя.
Поэтому Вам надо сместить указатель на начальную позицию, либо сохранить эту позицию во временной переменной с последующим восстановлением, например так:
{
char* tmp = str;
while(*str)
{
putchar (toupper(*(str++)));
}
str = tmp;
}
Либо так:
{
char* tmp = str;
while(*tmp)
{
putchar (toupper(*(str++)));
}
}
Тогда и деструктор вызывается корректно:
{
cout << "\nDeleting str\n";
delete [] str; //release memory
}
{ //uses 1-arg constructor
String s1 = "Who knows nothing doubts nothing.";
cout << "s1="; //display string
s1.display();
s1.upit();
cout<<endl;
s1.display();
return 0;
}
P.S. Все беды топикстартера из-за невнимательности...
Код в приложении.
Разве str=0; не выставляет указатель на начало?
Или Вы хотите сказать что str=0 не равно адресу первого элемента?
Это я погорячился. :p действительно разыменование..
Да, действительно я только вывожу ее на экран..
P.S.
И это тоже. Но еще ко всему тема по указателям идет тяжеловато..
Чем дальше двигаюсь по книге, тем больше раз перечитываю главы :)
Работает, но Вы не удалили выделенную под массив память (утечка)...:)
Или Вы хотите сказать что str=0 не равно адресу первого элемента?
Не выставляет и не равно адресу первого элемента. (адрес str станет равным 0x00000000)
Мой Вам совет - воспользуйтесь дебагером и Вы поймёте как работает программа...
Так вот что такое утечки памяти... :rolleyes: вот я сними и столкнулся..
Спасибо за помощь.