Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 10, средняя оценка - 4.90
Nicl
0 / 0 / 0
Регистрация: 07.10.2008
Сообщений: 26
#1

Проблема с классом и массивом char-ов - C++

14.11.2008, 18:52. Просмотров 1278. Ответов 9
Метки нет (Все метки)

Есть класс, содержащий одномерный массив из char-ов и методы для работы с ним. Проблема возникла в самом начале - не получается корректно изменить размер массива, а конкретно - удалить указатель перед сменой размера и во время запуска деструктора.

В .h:
C++
1
2
3
4
5
6
7
8
9
10
11
12
class CMyString
{
    int size;
    char* arr; //указатель на массив создается
public:
    CMyString(void);
    CMyString(int);
    ~CMyString(void);
    //CMyString operator+ (CMyString);
    //void input(char*);
    //void show(void);
};
В .cpp:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
CMyString::CMyString(void)
{
    delete[] arr;//удаляется заданный в .h указатель.
    char *arr= new char[16];//нет параметра  - размер 16
}
CMyString::CMyString(int size)
{
    delete[] arr;
    char *arr= new char[size];//есть параметр - размер size;
}
 
CMyString::~CMyString(void)
{
    delete[] arr; //деструктором удаляется указатель на массив. 
}
Вылетает при запуске с ошибкой.

Если же его не удалять, т.е. закомментировать все "delete[] arr" - проблема возникает на этапе заполнения массива.
C++
1
2
3
4
5
6
7
8
9
void CMyString::input(char* a)
{
 
    for (int i = 0; ; i++)
    {
    arr[i] = a[i];
    if (a[i] == '\0') break;
    }
}
Вылетает при запуске с ошибкой.

Помогите пожалуйста разобраться.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
14.11.2008, 18:52
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Проблема с классом и массивом char-ов (C++):

проблема с массивом типа CHAR - C++
нужно выполнить функцию fopen() . которая кушает на вход указатель на массив char в качестве пути к файлу ну и режим работы с файлом. ...

программа с массивом и классом..... - C++
Написал часть программы для составления некой базы 15 книг, где будет записано название книги и издательство, компилировал нету ошибок, но...

Программа с массивом и классом - C++
Добрый день. Нужно написать программу. Если пользователь вводит 1 - даем ему записать марку машины. Если пользователь вводит 2 - пишет...

Проблема с классом - C++
Доброе времени суток...у меня проблема в создании класса - динамического массива! проблема в изминении определённого элемента и вывода на...

Проблема с классом Вектор - C++
Здравствуйте! Не могу понять почему вместо значений вектора выводиться непонятные числа. Вот код: #include <vector> #include...

Проблема с классом для линейного списка - C++
Доброго времени суток! Начал писать класс для организации хранения данных в виде линейного списка, вот Header file:...

9
CheshireCat
Эксперт С++
2896 / 1245 / 78
Регистрация: 27.05.2008
Сообщений: 3,404
14.11.2008, 19:03 #2
1. Разумеется, если delete[] не закомментированы, будет вылетать с ошибкой сразу же. Чему у тебя равно arr, когда выполняется вход в тело конструктора, ась? Правильно, мусор там лежит.....
2. Почему вылетает при заполнении массива - ставь точку останова и вперед в отладчик! Чему у тебя равны в этот момент a и arr? Причин может быть много, код довольно таки стремный....
0
master.EXE
88 / 16 / 2
Регистрация: 10.03.2008
Сообщений: 101
14.11.2008, 19:22 #3
delete[] arr;//удаляется заданный в .h указатель.
char *arr= new char[16];//нет параметра - размер 16
Смотри, ты очищаешь память, выделенную под указатель arr, а затем создаешь новый указатель arr, который у тебя разрушается сразу же после выхода из конструктора.
Т.е. ты выделяешь память не под тот указатель arr, который у тебя описан в разделе private, а под совершенно новый локальный arr.
void CMyString::input(char* a)
{

for (int i = 0; ; i++)
{
arr[i] = a[i];
if (a[i] == '\0') break;
}
}
тут я могу посоветовать сделать так:
C++
1
2
3
4
5
void CMyString::input(char* a)
{
    for (int i = 0;a[i]!='\0'; i++)
        arr[i] = a[i];
}
Но это совет чисто по синтаксису. А вообще, я думаю что в этом месте прога у тебя вылетает по причине "неправильного" конструктора массива.
0
Nicl
0 / 0 / 0
Регистрация: 07.10.2008
Сообщений: 26
14.11.2008, 19:24  [ТС] #4
CheshireCat
1. Хм. А почему тогда вылетает при единственном delete[] в деструкторе? Да и почему это должно мешать удалить указатель-то? Он ж создан.
2. a задается снаружи, прописывание в заголовке функции (char* a = "abc") не спасает. А вот в теле функции конструкция arr = a прокатывает, т.е все со значениями хорошо.

master.EXE
А как правильно он должен выглядеть?
Опять же, смущают вылеты при наличии delete[] в деструкторе.
0
master.EXE
88 / 16 / 2
Регистрация: 10.03.2008
Сообщений: 101
14.11.2008, 19:41 #5
Цитата Сообщение от CheshireCat Посмотреть сообщение
1. Разумеется, если delete[] не закомментированы, будет вылетать с ошибкой сразу же. Чему у тебя равно arr, когда выполняется вход в тело конструктора, ась? Правильно, мусор там лежит.....
2. Почему вылетает при заполнении массива - ставь точку останова и вперед в отладчик! Чему у тебя равны в этот момент a и arr? Причин может быть много, код довольно таки стремный....
Возможно я чего-то не понимаю, но какая разница между тем от чего очищать выделенную память? Есть ли разница от того, лежит ли там мусор или ценные данные? Для машины (если она конечно не высокоинтеллектуальна) никакой разницы. Хотя, в то же время стандарты С++ оговаривают, что нужно использовать операцию delete только с теми переменными, которые были выделены операцией new. Так что, вполне возможно, что дело не в мусоре, который хранится изначально, а в чем-то другом...

Добавлено через 2 минуты 10 секунд
master.EXE
А как правильно он должен выглядеть?
Опять же, смущают вылеты при наличии delete[] в деструкторе.
1) Я думаю, что так:
C++
1
2
3
4
5
CMyString::CMyString(void)
{
    delete[] arr;//удаляется заданный в .h указатель.
    arr= new char[16];//нет параметра  - размер 16
}
2) Смотри, у тебя в разделе private насписано следующее:
C++
1
2
int size;
char* arr; //указатель на массив создается
Т.е. ты создаешь указатель arr, который указывает на тип char. Насколько я помню, стандарт языка С++ гласит, что пользоваться командой delete для указателя можно только тогда, когда память пож этот указатель была преждевременно выделена командой new. В противном случае, ситуация может быть любой.
1
Nicl
0 / 0 / 0
Регистрация: 07.10.2008
Сообщений: 26
14.11.2008, 21:01  [ТС] #6
master.EXE
Спасибо, про такой (arr = new ...) вариант не догадался.
Теперь работает и delete[] в деструкторе, и метод input.
Метод input немного переделал. Ваш вариант не подходит - после "переноса" всех символов не записывается "\0".
C++
1
2
3
4
5
    for (int i = 0;i<size ; i++)
    {
    arr[i] = a[i];
    if (a[i] == '\0') break;
    }
0
CheshireCat
Эксперт С++
2896 / 1245 / 78
Регистрация: 27.05.2008
Сообщений: 3,404
14.11.2008, 22:55 #7
Цитата Сообщение от master.EXE Посмотреть сообщение
Возможно я чего-то не понимаю, но какая разница между тем от чего очищать выделенную память? Есть ли разница от того, лежит ли там мусор или ценные данные? Для машины (если она конечно не высокоинтеллектуальна) никакой разницы. Хотя, в то же время стандарты С++ оговаривают, что нужно использовать операцию delete только с теми переменными, которые были выделены операцией new. Так что, вполне возможно, что дело не в мусоре, который хранится изначально, а в чем-то другом...
Да нет, именно в этом. Лень сейчас искать точную ссылку на пункт Стандарта, но он, родимый, утверждает: если память удаляется через delete[], то перед этим она должна быть выделена именно через new[] и никак иначе, в противном случае - поведение программы не определено (behavior is undefined). Надеюсь, ты понимаешь, что такое "поведение не определено"? Даже если прога не просто вылетит, а - отформатирует диск С:, это будет вполне логично и подпадает под определение "поведение не определено". То есть, программа может делать все, что ей заблагорассудится, - Стандарт не накладывает никаких ограничений и не дает никаких гарантий.
0
master.EXE
88 / 16 / 2
Регистрация: 10.03.2008
Сообщений: 101
15.11.2008, 07:33 #8
Цитата Сообщение от CheshireCat Посмотреть сообщение
Да нет, именно в этом. Лень сейчас искать точную ссылку на пункт Стандарта, но он, родимый, утверждает: если память удаляется через delete[], то перед этим она должна быть выделена именно через new[] и никак иначе, в противном случае - поведение программы не определено (behavior is undefined). Надеюсь, ты понимаешь, что такое "поведение не определено"? Даже если прога не просто вылетит, а - отформатирует диск С:, это будет вполне логично и подпадает под определение "поведение не определено". То есть, программа может делать все, что ей заблагорассудится, - Стандарт не накладывает никаких ограничений и не дает никаких гарантий.
Возможно я выражаюсь не понятно, но если ты хорошо перечитаешь мой пост, то ты увидишь, что ты написал тоже самое что и я. Я не сомневаюсь в том, что если память очищается через delete[], то перед этим она должна быть выделена именно через new[] и никак иначе. Мое сомнение в другом:
1. Разумеется, если delete[] не закомментированы, будет вылетать с ошибкой сразу же. Чему у тебя равно arr, когда выполняется вход в тело конструктора, ась? Правильно, мусор там лежит.....
Т.е. до этого ты основывал свое мнение на том, что там лежит мусор. Не так ли?
0
Nicl
0 / 0 / 0
Регистрация: 07.10.2008
Сообщений: 26
15.11.2008, 16:21  [ТС] #9
Немного продвинулся вперед.
Проблемы возникли при перегрузке оператора "+" под конкатенацию.
От кода не зависит - вылетает даже так:
C++
1
2
3
4
5
6
CMyString CMyString::operator+ (CMyString x)
{
        CMyString t(15);
        t.input("abc");
    return t;
}
Проблема в том, что деструктор выполняется 2 раза - соответственно при выполнении delete[] arr происходит ошибка.
Память под arr выделена в конструкторе (arr = new char[size]);

---

Не удается справиться и с перегрузкой оператора вывода в поток.
Реализую так:
.h:
C++
1
2
3
4
#include <iostream>
...
friend ostream& operator<<(ostream&, CMyArray&);
...
.cpp:
C++
1
2
3
4
5
6
7
8
#include <iostream>
...
friend ostream& CMyString::operator<<(ostream& os, CMyString& a)
 
{
    return os;
}
...
Не компилируется, выдаются десятки ошибок.
0
Nicl
0 / 0 / 0
Регистрация: 07.10.2008
Сообщений: 26
19.11.2008, 17:04  [ТС] #10
Проблема с деструктором была вызвана отсутствием перегруженного оператора =.

А вот с выводом/вводом в поток совсем никак.
.h:
C++
1
2
3
4
#include <iostream>
...
friend ostream & operator<< (ostream&, CMyString&);
...
.cpp:
C++
1
2
3
4
5
6
7
#include <iostream>
...
ostream & operator<< (ostream & s, CMyString & a)
{
    return os;
}
...
Вроде все правильно, но не компилируется.
0
19.11.2008, 17:04
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
19.11.2008, 17:04
Привет! Вот еще темы с ответами:

Работа с массивом char - C++
Вот задание Вам дана непустая строка, состоящая из строчных латинских букв, цифр и пробелов. Длина строки не превышает 250 символов....

Работа с массивом char - C++
Товарищи подскажите пожалуйста, не могу никак понять в чём проблема. Есть массив скажем: int X; X = 1; X = 2; X = 3; X = 4; ...

Работа с массивом char - C++
Добрый день. Объясните, если не сложно, на пальцах в чем ошибка? char*my1={&quot;first my1&quot;,&quot;second my1&quot;}; my1='E'; Синтаксически все...

Задание с массивом типа char - C++
Нужно удалить все столбцы в которых есть хотя бы одна буква 'а'.Ошибка в delA,но не знаю как исправить #include &lt;cstdlib&gt; #include...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.