0 / 0 / 0
Регистрация: 23.08.2020
Сообщений: 19

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

26.03.2021, 17:42. Показов 3549. Ответов 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
12887 / 6749 / 1812
Регистрация: 18.10.2014
Сообщений: 17,075
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
12887 / 6749 / 1812
Регистрация: 18.10.2014
Сообщений: 17,075
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
12887 / 6749 / 1812
Регистрация: 18.10.2014
Сообщений: 17,075
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
6340 / 5481 / 1109
Регистрация: 11.10.2019
Сообщений: 14,589
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
12887 / 6749 / 1812
Регистрация: 18.10.2014
Сообщений: 17,075
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
Ответ Создать тему
Опции темы

Новые блоги и статьи
Система статов в Unity
GameUnited 20.04.2025
Статы — фундаментальный элемент игрового дизайна, который определяет характеристики персонажей, предметов и других объектов в игровом мире. Будь то показатель силы в RPG, скорость передвижения в. . .
Статические свойства и методы в TypeScript
run.dev 20.04.2025
TypeScript прочно занял своё место в системе современной веб-разработки. Этот строго типизированный язык программирования не просто расширяет возможности JavaScript — он делает разработку более. . .
Batch Transform и Batch Gizmo Drawing API в Unity
GameUnited 20.04.2025
В мире разработки игр и приложений на Unity производительность всегда была критическим фактором успеха. Создатели игр постоянно балансируют между визуальной привлекательностью и плавностью работы. . .
Звук в Unity: Рандомизация с Audio Random Container
GameUnited 20.04.2025
В современных играх звуковое оформление часто становится элементом, который либо полностью погружает игрока в виртуальный мир, либо разрушает атмосферу за считанные минуты. Представьте: вы исследуете. . .
Максимальная производительность C#: Советы, тестирование и заключение
stackOverflow 20.04.2025
Погружение в мир микрооптимизаций C# открывает перед разработчиком целый арсенал мощных техник. Но как определить, где и когда их применять? Ответ начинается с точных измерений и профилирования. . . .
Максимальная производительность C#: Предсказание ветвлений
stackOverflow 20.04.2025
Третий ключевой аспект низкоуровневой оптимизации — предсказание ветвлений. Эта тема менее известна среди разработчиков, но её влияние на производительность может быть колоссальным. Чтобы понять. . .
Максимальная производительность C#: Векторизация (SIMD)
stackOverflow 20.04.2025
Помимо работы с кэшем, другим ключевым аспектом низкоуровневой оптимизации является векторизация вычислений. SIMD (Single Instruction, Multiple Data) позволяет обрабатывать несколько элементов данных. . .
Максимальная производительность C#: Процессорный кэш
stackOverflow 20.04.2025
Знакомство с внутренним устройством процессорного кэша — ключевой шаг в написании по-настоящему быстрого кода на C#. Этот слой архитектуры компьютера часто ускользает от внимания разработчиков, но. . .
Максимальная производительность C#: Введение в микрооптимизации
stackOverflow 20.04.2025
В мире разработки на C# многие привыкли полагаться на . NET Runtime, который "магическим образом" сам оптимизирует код. И часто это работает - современные JIT-компиляторы творят чудеса. Но когда речь. . .
MVC фреймворк в PHP
Jason-Webb 19.04.2025
Архитектурный паттерн Model-View-Controller (MVC) – это не просто модный термин из мира веб-разработки. Для PHP-программистов это фундаментальный подход к организации кода, который радикально меняет. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru
Выделить код Копировать код Сохранить код Нормальный размер Увеличенный размер