Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.83/18: Рейтинг темы: голосов - 18, средняя оценка - 4.83
0 / 0 / 0
Регистрация: 23.08.2020
Сообщений: 19

Ошибка при чтении символов строки при создании объекта класса

26.03.2021, 17:42. Показов 3540. Ответов 9

Author24 — интернет-сервис помощи студентам
У меня имеется класс Song, в котором присутствуют поля имени песни (Name) и длительности песни (Duration). Также в этом классе есть конструктор, заполняющий поля стандартными значениями. При создании такого объекта в main() смотрю через отладчик, что в поле Name (а именно - Name -> _MyPair -> Базовое представление -> _MyVal2 -> _Bx -> _Ptr) есть надпись - "ошибка при чтении символов строки". Причем странно, что все время все компилилось и работало, но сегодня почему-то вылезло такое. Короче, сам код:
C++ Скопировано
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Song
{
private:
    std::string Name;
    int Duration;
 
public:
    Song()
    {
        this->Name = "";
        this->Duration = 0;
    }
}
 
int main()
{
Song* song = new Song;
 
/* ... */
}
Пробовал уже и само поле инициализировать, и способ задания имени в конструкторе менять на такой, все без толку:
C++ Скопировано
1
this->Name = {}
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
26.03.2021, 17:42
Ответы с готовыми решениями:

Ошибка при чтении объекта класса из файла
Долго я пытался решить проблему самостоятельно, а так же и искал ответы на форумах. Но в итоге не смог решить свою проблему. Проблема...

Ошибка при создании объекта класса
Приветствую, форумчане! Возник вопрос при создании объекта класса String. Что самое интересное, когда пишу ту же прогу без параметров в...

Ошибка при создании объекта класса
Здравствуйте. В коде ниже при попытке вывести код на экран возникает следующая ошибка: prog.cpp: In function 'int main()': ...

9
0 / 0 / 0
Регистрация: 23.08.2020
Сообщений: 19
27.03.2021, 05:49  [ТС]
Примечательно еще то, что у меня есть другие классы тоже с полем string Name и с аналогичными конструкторами, но там все с этими именами в порядке. Глюк какой, что ли...
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12875 / 6739 / 1810
Регистрация: 18.10.2014
Сообщений: 17,065
27.03.2021, 06:09
Цитата Сообщение от Skel Посмотреть сообщение
смотрю через отладчик, что в поле Name (а именно - Name -> _MyPair -> Базовое представление -> _MyVal2 -> _Bx -> _Ptr) есть надпись - "ошибка при чтении символов строки". Причем странно, что все время все компилилось и работало, но сегодня почему-то вылезло такое
Не понял. Где проблема? Зачем вы туда полезли смотреть? У вас что-то не работало? Если что-то не работало - то пишите, что именно.

Также: где в вашем вопросе написано, какую реализацию std::string вы использовали? Компилятор? Отладчик?

Внутреннее представление класса std::string зависит от реализации и может быть оптимизировано массой разных способов, особенно для коротких или пустых строк. Вполне возможно, что для такой - пустой - строки через этот указатель и не должно быть видно никаких осмысленных символов. Да, и я тоже вижу, что у меня в Visual Studio в таком примере поле ... _Bx -> _Ptr содержит мусор. Это нормально.

Возьмите строку подлиннее, и вы увидите, что, начиная с какой-то длины (16 символов?), начнет использоваться поле ... _Bx -> _Ptr.

Еще раз: где описание реальной проблемы, которую вы пытаетесь решить? Что не работает?

Цитата Сообщение от Skel Посмотреть сообщение
Глюк какой, что ли...
Не нужно строить фантастических теорий, когда вполне естественное и логичное объяснение лежит на поверхности.
0
0 / 0 / 0
Регистрация: 23.08.2020
Сообщений: 19
27.03.2021, 06:29  [ТС]
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Зачем вы туда полезли смотреть? У вас что-то не работало?
Да, я потом использую эту переменную Name для проверки имени на соответствие. Пользователь вводит название песни, прога проверяет все альбомы на подходящие песни и возвращает первую найденную. В альбомах по 4 песни. Как работает цикл: пока имя песни не пустое значение, то проверяй ее на соответствие, иначе переходи к следующему альбому. В первом альбоме 4 песни он проверяет нормально, но как только доходит до следующей песни (которой по факту не существует, там должен мусор лежать), там лежит "ошибка чтения символов строки", и выдает исключение bad_alloc.

Цитата Сообщение от TheCalligrapher Посмотреть сообщение
содержит мусор. Это нормально.
Если бы просто мусор - то да, нормально. Но туда почему-то записывается именно ошибка. Код скину в след. посте, чтоб этот не нагромождать.

Добавлено через 6 минут
У меня еще есть класс Band (это сама группа, но она не так важна, там лишь метод сравнения песен лежит, который нужен).
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
class Song
{
private:
    std::string Name;
    int Duration;
 
public:
    Song()
    {
        this->Name = "";
        this->Duration = 0;
    }
std::string GetSongName()
    {
        return this->Name;
    }
};
 
class Album
{
private:
    std::string Name;
    int ReleaseYear;
    Song* Songs;
 
public:
    Album()
    {
        this->Name = "";
        this->ReleaseYear = 1900;
        this->Songs = { };
    }
 
Song* GetAlbumSongs()
    {
        return this->Songs;
    }
};
 
class Band
{
private:
    std::string Name;
    std::string Description;
    Album* Albums;
 
public:
    Band()
    {
        this->Albums = {};
        this->Description = "";
        this->Name = "";
    }
Album* GetBandAlbums()
    {
        return this->Albums;
    }
 
Song* FindSong(std::string songTitle, int albCount)
    {
        int b = 0;
        int g = 0;
 
        for (int i = 0; i < albCount; ++i)
        {
            b = 0;
            while (this->GetBandAlbums()[i].GetAlbumSongs()[b].GetSongName() != "") // проверка, пока имя песни не пустое значение
            {
 
                if this->GetBandAlbums()[i].GetAlbumSongs()[b].GetSongName() == songTitle) // сравнение имени песни
                {
                    return this->GetBandAlbums()[i].GetAlbumSongs();
                }
                ++b;
 
            }
        }
 
        return nullptr;
    }
}
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12875 / 6739 / 1810
Регистрация: 18.10.2014
Сообщений: 17,065
27.03.2021, 06:39
Цитата Сообщение от Skel Посмотреть сообщение
Если бы просто мусор - то да, нормально. Но туда почему-то записывается именно ошибка.
Вы делаете какие-то дикие и странные фантасмагорические выводы. С чего вы взяли, что туда "записывается именно ошибка"? Никакая "ошибка" туда не записывается.

Поле ... _Bx -> _Ptr в отладочном режиме содержит 0x6161616161616161 или 0xcdcdcdcdcdcdcd00, т.е. какое-то явно специально выбранное бессмысленно-мусорное указательное значение. А сообщение об "ошибке" вам пишет уже отладчик. Никуда это сообщение не "записывается".

Цитата Сообщение от Skel Посмотреть сообщение
и выдает исключение bad_alloc.
Никакого отношения к теме ... _Bx -> _Ptr эта ошибка не имеет. Вы накосячили где-то совсем в другом месте.
0
0 / 0 / 0
Регистрация: 23.08.2020
Сообщений: 19
27.03.2021, 06:40  [ТС]
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Вы делаете какие-то дикие и странные фантасмагорические выводы
Однако прога перестала работать ни с того ни с сего. Пошел в отладчик и нашел такое. Раньше этого не было. Ничего я у класса песни не менял. Так ведь заметь, что в других классах с именами все в порядке, с песнями почему-то такое приключилось
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12875 / 6739 / 1810
Регистрация: 18.10.2014
Сообщений: 17,065
27.03.2021, 06:50
Лучший ответ Сообщение было отмечено Skel как решение

Решение

Цитата Сообщение от Skel Посмотреть сообщение
Пошел в отладчик и нашел такое. Раньше этого не было.
Нет, вы выдумываете. Это было всегда. Это совершенно нормальное поведение std::string.

Цитата Сообщение от Skel Посмотреть сообщение
Однако прога перестала работать ни с того ни с сего.
Еще раз: никакого отношения к теме ... _Bx -> _Ptr ваше "перестала работать" не имеет. Вы накосячили где-то совсем в другом месте.

Перестаньте заниматься фигней и разглядывать ... _Bx -> _Ptr, а ищите у себя косяки: вылет за пределы массива, обращение к удаленной памяти и т.п.

Добавлено через 6 минут
Цитата Сообщение от Skel Посмотреть сообщение
В первом альбоме 4 песни он проверяет нормально, но как только доходит до следующей песни (которой по факту не существует, там должен мусор лежать)
Чего? Это что за белиберда? Какое еще "должен мусор лежать"?

Ваш цикл поиска песни написан так, что последовательность песен в альбоме обязательно (!) должна заканчиваться песней с пустым именем. Не "мусором", а песней с пустым именем (!). Если в альбоме 4 песни, то размер массива песен должен равняться 5 и последняя "фиктивная" песня должна иметь пустое имя. Если вы не соблюдете это жесткое правило, программа будет падать.
1
0 / 0 / 0
Регистрация: 23.08.2020
Сообщений: 19
27.03.2021, 07:13  [ТС]
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Возьмите строку подлиннее
Смотри, я в конструкторе изменил поле присвоения названия песни на 20-25 букв d, вместо "" (как ты и сказал, взять строку подлиннее). И заработало. Возвращаю обратно на пустое имя - ошибка. Как так-то? Неужели мне теперь по стандарту каждой песни какое-то имя из 15+ букв задавать? Некрасиво как-то.

Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Чего? Это что за белиберда?
Цикл безотказно работает. При встрече с мусором он его считает за пустую строку и просто переходит к след. альбому.

Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Если в альбоме 4 песни, то размер массива песен должен равняться 5 и последняя "фиктивная" песня должна иметь пустое имя
Зачем выделять место еще для одной лишней песни? Вот если б разговор про выделение памяти под символы, то да, выделять нужно на 1 больше заявленного размера для '\0'.
UPD. Хм, точно, выделил на 1 больше размер массива - все теперь работает и с пустым значением строки. Спасибо большое!
0
фрилансер
 Аватар для Алексей1153
6337 / 5476 / 1108
Регистрация: 11.10.2019
Сообщений: 14,585
27.03.2021, 07:29
Skel, Вот ещё вариант с STL, смотри, насколько всё проще )) Не нужно три дня штурмовать форум, десять минут - и всё готово

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
#include <iostream>
#include <vector>
#include <optional>
 
class Song
{
public:
    std::string Name;
    int Duration{};
};
 
class Album
{
public:    
    std::string Name;
    std::vector<Song> Songs;
    int ReleaseYear{1900};
};
 
class Band
{
public:    
    std::string Name;
    std::string Description;
    std::vector<Album> Albums;
 
    std::optional<Song> FindSong(const std::string_view songTitle)const
    {
        for(const auto& Album:Albums)
        {
            for(const auto& song:Album.Songs)
            {
                if(song.Name==songTitle)
                {
                    return song;
                }
            }
        }
 
        return {};
    }
};
 
int main()
{
    Song s;
    s.Name="Hello";
    
    Album a;
    a.Name="Fallen";
    a.Songs.push_back(s);
    
    Band b;
    b.Name="Evanescence";
    b.Albums.push_back(a);
    
    if(auto song=b.FindSong("Hello"))
    {
        std::cout<<"song name: "<<song->Name<<'\n';
    }
}
1
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12875 / 6739 / 1810
Регистрация: 18.10.2014
Сообщений: 17,065
27.03.2021, 07:33
Цитата Сообщение от Skel Посмотреть сообщение
Цикл безотказно работает. При встрече с мусором он его считает за пустую строку и просто переходит к след. альбому.
Ым... Што????

При встрече с "мусором" происходит неопределенное поведение и ваша программа падает во все воронье горло. А то, что вам раньше казалось, что она не падала - это вы ее просто плохо тестировали.

Цитата Сообщение от Skel Посмотреть сообщение
Зачем выделять место еще для одной лишней песни?
Чтобы программа не падала. Вам нужно иметь возможность определить фактический размер массива, чтобы не вылетать за его пределы. А как вы это будете делать - ваше дело.

Разумнее/экономнее было бы хранить размер массива, как это делает std::vector, а не цеплять в конце массива дополнительную фиктивную песню с пустым именем. Но и так тоже можно. А еще разумнее было бы просто использовать std::vector.

Главное - если вы будете рассчитывать на ваше наивное "при встрече с мусором он его считает за пустую строку", то ваша программа будет просто падать.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
27.03.2021, 07:33
Помогаю со студенческими работами здесь

Ошибка при создании объекта класса
Привет! Чтобы на протяжении всего поста было понятно о чём я говорю,в конце поста прикреплю код. Так вот, при создании объекта класса...

Ошибка при создании объекта класса
Есть класс, создаю объект, выходит ошибка &quot;cannot allocate an object of abstract type 'Cat'&quot; Что делать? cat.h: #ifndef CAT_H ...

Ошибка в работе класса при создании нового объекта
Здравствуйте. Есть код класса при котором всё работает прекрассно когда один экземпляр, а когда создается второй то выдает...

Ошибка при чтении символов строки
Ошибка при чтении key_text при вызове метода object_yes_no(), почему? //Создание класса указателей с наследниками-объектами ...

Ошибка при чтении символов строки
Здравствуйте, уважаемые форумчане! Решил вспомнить программирование и написать программу, которая определяла бы слово-полиндром. Все...


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

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Новые блоги и статьи
Списки и кортежи в Python: различия, особенности, применение
py-thonny 13.04.2025
Python славится своей гибкостью при работе с данными. В арсенале языка есть две основные последовательные структуры данных, которые программисты используют ежедневно — списки и кортежи. Эти структуры. . .
Middleware в ASP.NET Core
UnmanagedCoder 13.04.2025
В ASP. NET Core термин "middleware" занимает особое место. Что же это такое? Middleware представляет собой программные компоненты, которые формируют конвейер обработки HTTP-запросов в приложении. . . .
Таблицы лута в Unity с MinMaxCurve и AnimationCurve
GameUnited 12.04.2025
Создание сбалансированного лута в играх — задача не из простых. Разработчики постоянно ищут способы настройки систем выпадения предметов, которые будут одновременно справедливыми для игроков и. . .
std::expected в C++: Управление ошибками
bytestream 12.04.2025
Обработка ошибок всегда была важной и одновременно сложной задачей в программировании на C++. На протяжении долгого времени разработчики использовали различные подходы: возвращаемые коды ошибок,. . .
Nullable типы и операторы объединения null в C#
UnmanagedCoder 12.04.2025
Многие шутят, что null — это миллиардная ошибка в программировании. И в этой шутке только доля шутки. Тони Хоар, создатель null-ссылки, сам назвал её своей "ошибкой на миллиард долларов". Почему?. . .
Аутентификация и авторизация JWT в микросервисах с API Gateway
stackOverflow 12.04.2025
В традиционных монолитных приложениях безопасность часто реализуется как единый защитный периметр - пользователь проходит аутентификацию один раз, после чего получает доступ ко всем функциям системы. . . .
TypeScript: Интерфейсы vs Типы
run.dev 11.04.2025
Современная разработка на JavaScript сталкивается с множеством проблем при масштабировании проектов. Типизация кода стала хорошим инструментом, помогающим избежать ошибок во время выполнения,. . .
Управление топиками и разделами Kafka
Javaican 11.04.2025
Apache Kafka — распределенная платформа потоковой передачи данных, которая стала стандартом для построения высоконагруженных систем обмена сообщениями. В современной архитектуре микросервисов,. . .
Миграция монолита в Event-Driven микросервисную архитектуру на C#
stackOverflow 11.04.2025
Монолитная архитектура – классический подход к разработке программного обеспечения. Это приложение, построенное как единое целое, где все компоненты тесно связаны между собой. Большинство проектов. . .
Go в Kubernetes: Управление ресурсами
golander 11.04.2025
Разработчики Go-приложений в Kubernetes часто сталкиваются с неожиданными проблемами производительности и даже внезапными отказами контейнеров. Причина этого кроется в особенностях взаимодействия. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru
Выделить код Копировать код Сохранить код Нормальный размер Увеличенный размер