Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.80/5: Рейтинг темы: голосов - 5, средняя оценка - 4.80
Саша Перков
0 / 0 / 0
Регистрация: 07.08.2014
Сообщений: 72
1

Ошибка при перегрузке оператора +

07.09.2016, 23:34. Просмотров 831. Ответов 13
Метки нет (Все метки)

Имеется класс, который представляет из себя строку и количество символов в ней. Задача - перегрузить оператор +, чтобы он складывал нам две строки и выдавал третью. Сделал я, по советам местных форумчан, это так:
C++
1
2
3
4
5
6
7
8
9
String operator+(String & a, String & b)
{
    String c;
    c.i = a.i + b.i;
    c.p = new char[c.i + 1];
    strcat(c.p, a.p);
    strcat(c.p + a.i, b.p);
    return c;
}
i - это размер строки
p - указатель на char
delete присутствует в деструкторе.

Но при выполнении программы вылезает ошибка:
"Возникло необработанное исключение по адресу 0x76F5C41F в Проект4.exe: исключение Microsoft C++: std::bad_alloc по адресу памяти 0x0043FA0C."
В чем может быть проблема, потому что все остальное работает нормально, но вот со сложением объектов такая беда. Могу предоставить остальной код, если надо, просто он большой и размещен в трех файлах. Заранее спасибо.
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
07.09.2016, 23:34
Ответы с готовыми решениями:

Ошибка при перегрузке оператора >>
Приветствую. Есть 2 класса: enum Color { white = 1, red, green, blue, yellow...

Ошибка при перегрузке оператора cin >>
#include <iostream> using namespace std; ...

Ошибка при перегрузке оператора вывода в файл
Добрый день, есть такой кусок кода: #include <iostream> #include...

Ошибка в перегрузке оператора - при работе с массивами
Текст программы: #include <iostream> #include <windows.h> using namespace...

Ошибка при перегрузке оператора, не знаю как исправить
#pragma once #include <iostream> #include <vector> #define innerVectorType...

13
DU3
281 / 233 / 115
Регистрация: 07.09.2016
Сообщений: 587
07.09.2016, 23:54 2
bad_alloc - это new не смог отработать. возможно слишком много попросили выделить.
надо узнать значение выражения в квадратных скобках: c.i + 1.
чему оно равно?
на случай если с дебагером не работали полезная инфа: Как пользоваться отладчиком (в Visual Studio)
0
Саша Перков
0 / 0 / 0
Регистрация: 07.08.2014
Сообщений: 72
08.09.2016, 09:18  [ТС] 3
Цитата Сообщение от DU3 Посмотреть сообщение
bad_alloc - это new не смог отработать. возможно слишком много попросили выделить.
надо узнать значение выражения в квадратных скобках: c.i + 1.
чему оно равно?
на случай если с дебагером не работали полезная инфа: Как пользоваться отладчиком (в Visual Studio)
Вот что я понял с помощью отладчика. Оператор new выделяет место для указателя и забивает в указатель мусор из символов. В следующей строке к этому мусору прибавляется моя первая строка. Естественно в строку все это не влезает. Что с этим можно сделать? Со значением c.i все нормально. Если вводить не большие строки, то и число будет маленькое.
0
zss
Модератор
Эксперт С++
7178 / 6677 / 4226
Регистрация: 18.12.2011
Сообщений: 17,622
Завершенные тесты: 1
08.09.2016, 09:56 4
Цитата Сообщение от Саша Перков Посмотреть сообщение
strcat(c.p, a.p);
strcat(c.p + a.i, b.p);
C++
1
2
strcpy(c.p, a.p); 
strcat(c.p, b.p);
0
Саша Перков
0 / 0 / 0
Регистрация: 07.08.2014
Сообщений: 72
08.09.2016, 15:21  [ТС] 5
Не помогло. Тоже самое происходит. Хотя по отладке все нормально. Функция даже нормально возвращает значение. Но уже в main происходит ошибка.
0
DU3
281 / 233 / 115
Регистрация: 07.09.2016
Сообщений: 587
08.09.2016, 22:29 6
если String - это ваша самодельная строка - то неплохо бы весь код выложить. Ошибка может быть и в другом месте.
std::bad_alloc - это исключение, которое при new может сгенерироваться. strcpy - это сишные функции, которые исключений не генерируют. ну и если код выложить не получится - студии можно сказать, чтобы она останавливалась в точке генерации исключения и с этого места можно пройтись по стеку и посмотреть, откуда все таки взялся баг.
0
Саша Перков
0 / 0 / 0
Регистрация: 07.08.2014
Сообщений: 72
08.09.2016, 22:58  [ТС] 7
Цитата Сообщение от DU3 Посмотреть сообщение
если String - это ваша самодельная строка - то неплохо бы весь код выложить. Ошибка может быть и в другом месте.
std::bad_alloc - это исключение, которое при new может сгенерироваться. strcpy - это сишные функции, которые исключений не генерируют. ну и если код выложить не получится - студии можно сказать, чтобы она останавливалась в точке генерации исключения и с этого места можно пройтись по стеку и посмотреть, откуда все таки взялся баг.
Смотрел. Сам не понял. Код сейчас весь скину.

Добавлено через 1 минуту
Заголовочный файл:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <string>
#include <iostream>
 
using namespace std;
 
class String
{
public:
    String();
    String(char[]);
    String(String &);
    
    ~String();
 
    friend istream & operator >> (istream & is, String  &);
    friend ostream & operator << (ostream & is, String  &);
    friend bool operator > (String &, String &);
    friend bool operator < (String &, String &);
    friend String operator+ (String &, String &);
    String & operator= (String &);
 
 
    int Lange();
 
private:
    int i;
    char *p;
};
Определения функций:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#include <iostream>
#include <string>
#include <cstring>
#include <cctype>
#include <fstream>
#include "Header.h"
#include <sstream>
 
using namespace std;
 
String::String()
{
    i = 1;
    p = '\0';
}
 
String::String(char s[])
{
    i = strlen(s);
    strcpy(p, s);
}
String::~String()
{
    delete p;
}
String::String(String & Str)
{
    p = new char[Str.i + 1];
    strcpy(p, Str.p);
}
 
 
istream & operator>>(istream & is, String & Str)
{
    char temp[1000];
    is.getline(temp, 1000);
    Str.i = strlen(temp);
    Str.p = new char[Str.i];
    strcpy(Str.p, temp);
    return is;
}
ostream & operator<<(ostream & is, String & Str)
{
    is << Str.p;
    return is;
}
bool operator>(String & a, String & b)
{
    if ((*a.p) > *(b.p))
        return true;
    else
        return false;
}
bool operator<(String & a, String & b)
{
    if ((*a.p) < *(b.p))
        return true;
    else
        return false;
}
String operator+(String & a, String & b)
{
    String c;
    c.i = a.i + b.i;
    c.p = new char[c.i + 1];
    strcpy(c.p, a.p);
    strcat(c.p, b.p);
    return c.p;
}
 
String & String::operator=(String & Str)
{
    i = Str.i;
    p = new char[i+1];
    strcpy(p, Str.p);
    return *this;
}
int String::Lange()
{
    return strlen(p);
}
Основной файл:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
#include <string>
#include "Header.h"
#include <cctype>
#include <fstream>
 
using namespace std;
 
 
 
int main()
{
    setlocale(LC_ALL, "Russian");
 
    String x, y, z;
    cin >> x;
    y = x;
    cout << y;
 
    system("pause");
    return 0;
}
0
DU3
281 / 233 / 115
Регистрация: 07.09.2016
Сообщений: 587
08.09.2016, 23:10 8
в конструкторе неверная инициализация указателя:
C++
1
2
3
4
5
6
String::String()
{
    i = 1; // ???
    //p = '\0';
    p = nullptr;
}
в строке 38 забили еденицу для нулевого байта. я не очень понял, надо эту еденицу к i добавлять или не надо.
в общем памяти должно быть выделено на один байт больше, чем длина строки.
C++
1
2
// Str.p = new char[Str.i];
Str.p = new char[Str.i + 1];
0
Саша Перков
0 / 0 / 0
Регистрация: 07.08.2014
Сообщений: 72
08.09.2016, 23:58  [ТС] 9
Цитата Сообщение от DU3 Посмотреть сообщение
в строке 38 забили еденицу для нулевого байта. я не очень понял, надо эту еденицу к i добавлять или не надо.
в общем памяти должно быть выделено на один байт больше, чем длина строки.
Все сделал, но все-равно такая же фигня. "нарушение прав доступа при записи по адресу 0xCCCCCCCC" причем адрес такой всегда. Да, и что нужно сделать с i в конструкторе тогда? Если не 1.
0
DU3
281 / 233 / 115
Регистрация: 07.09.2016
Сообщений: 587
09.09.2016, 00:09 10
Лучший ответ Сообщение было отмечено Саша Перков как решение

Решение

вам должно быть виднее. вы же класс придумали. конкретно ваш пример у меня отрабатывал без крашей. если вы еще как-то начали строки использовать - то не удивительно. например не инцициализирован указатель в String::String(char s[]), а него уже пытаются скопировать. в целом все очень и очень печально. прокачивайте дальше дебаггер, если эта работа не первая - это сэкономит вам кучу времени в будущем. еще вариант - поискать реализацию самодельных строк в сети. например тут на форуме таких строк и их разборок несчетное количество.
0
Саша Перков
0 / 0 / 0
Регистрация: 07.08.2014
Сообщений: 72
09.09.2016, 00:18  [ТС] 11
Цитата Сообщение от DU3 Посмотреть сообщение
вам должно быть виднее. вы же класс придумали. конкретно ваш пример у меня отрабатывал без крашей. если вы еще как-то начали строки использовать - то не удивительно. например не инцициализирован указатель в String::String(char s[]), а него уже пытаются скопировать. в целом все очень и очень печально. прокачивайте дальше дебаггер, если эта работа не первая - это сэкономит вам кучу времени в будущем. еще вариант - поискать реализацию самодельных строк в сети. например тут на форуме таких строк и их разборок несчетное количество.
Да только только учу классы. Вот для практики попробовал такое написать. Я был бы очень признателен, если бы Вы указали бы мне на косяки или иные плохие моменты. Это помогло бы мне в будущем. Да, и что можно сделать с char s[] ?

Добавлено через 6 минут
Все, с вашей помощью я нашел ошибку. Спасибо Вам огромное. Переделал один из конструкторов:
C++
1
2
3
4
5
6
String::String(char s[])
{
    i = strlen(s);
    p = new char[i + 1];
    strcpy(p, s);
}
Отладчиком никак не смог выявить эту проблему. Но в будущем буду стараться.
0
DU3
281 / 233 / 115
Регистрация: 07.09.2016
Сообщений: 587
09.09.2016, 00:20 12
практикуйтесь дальше. хождение по граблям положительно сказывается на усваивании матчасти .
косяки конкретно вашего класса должны быть расписаны в любом учебнике.
еще раз повторюсь - изучите возможности дебагера и научитесь с ним работать. потраченное на него время окупится, если с программированием у вас надолго.
0
Саша Перков
0 / 0 / 0
Регистрация: 07.08.2014
Сообщений: 72
09.09.2016, 00:37  [ТС] 13
Цитата Сообщение от DU3 Посмотреть сообщение
практикуйтесь дальше. хождение по граблям положительно сказывается на усваивании матчасти .
косяки конкретно вашего класса должны быть расписаны в любом учебнике.
еще раз повторюсь - изучите возможности дебагера и научитесь с ним работать. потраченное на него время окупится, если с программированием у вас надолго.
Как посоветуете изучить возможности дебагера? Учебники, видео, гайды, руководства?
0
zss
Модератор
Эксперт С++
7178 / 6677 / 4226
Регистрация: 18.12.2011
Сообщений: 17,622
Завершенные тесты: 1
09.09.2016, 07:29 14
ПО отладчику здесь есть тема
Как пользоваться отладчиком (в Visual Studio)
0
09.09.2016, 07:29
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
09.09.2016, 07:29

Ошибка в перегрузке оператора +=
В строках 42-50 пытаюсь описать перегрузку операции +=, но выдаёт ошибку...

Ошибка в перегрузке оператора
Не пойму в чем дело(( Имеется класс вектор ,вычислил длину,а теперь очу...

Ошибка в перегрузке оператора +=
#include &lt;iostream.h&gt; #include &lt;string.h&gt; #include &lt;windows.h&gt; const int...


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

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

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