Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.72/25: Рейтинг темы: голосов - 25, средняя оценка - 4.72
 Аватар для anapshy
531 / 272 / 220
Регистрация: 14.11.2016
Сообщений: 1,052

Нарушение доступа к чтению в VS (ООП)

23.07.2017, 23:21. Показов 4898. Ответов 13
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
C++
1
2
3
Вызвано исключение: нарушение доступа для чтения.
std::_String_alloc<std::_String_base_types<char,std::allocator<char> > >::_Myres(...) вернул 0x1C.
Если для этого исключения имеется обработчик, выполнение программы может быть продолжено безопасно.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/*file xstring*/
bool _Grow(size_type _Newsize,
        bool _Trim = false)
        {   // ensure buffer is big enough, trim to size if _Trim is true
        if (max_size() < _Newsize)
            _Xlen();    // result too long
        if (this->_Myres() < _Newsize) /* указывает на эту строку */
            _Copy(_Newsize, this->_Mysize());   // reallocate to grow
        else if (_Trim && _Newsize < this->_BUF_SIZE)
            _Tidy(true, // copy and deallocate if trimming to small string
                _Newsize < this->_Mysize() ? _Newsize : this->_Mysize());
        else if (_Newsize == 0)
            _Eos(0);    // new size is zero, just null terminate
        return (0 < _Newsize);  // return true only if more work to do
        }
Собственно сам код программы:
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 <string>
#include <conio.h>
 
class A
{
protected:
    std::string str;
public:
    A(void) : str("None") {};
    virtual ~A(void) = default;
    void setStr(const std::string &_s)
    {
        str = _s;
    }
    virtual void test(void) = 0;
};
 
class B final : public A
{
public:
    B(void) : A() {};
    virtual ~B(void) = default;
    void test(void) override
    {
        std::cout << this->str << std::endl;
    }
};
 
void set_memory(A *obj)
{
    std::cout << "Press key '1'" << std::endl;
    while (true)
    {
        switch (_getch())
        {
        case '1':
            obj = new B();
            break;
        default:
            continue;
        }
        break;
    }
}
 
int main(void)
{
    A *a(NULL);
    set_memory(a);
    std::string str;
    std::cout << "Enter the string: ";
    std::cin >> str;
    a->setStr(str);
    a->test();
 
    delete a;
 
    _getch();
    return EXIT_SUCCESS;
}
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
23.07.2017, 23:21
Ответы с готовыми решениями:

Строки. Нарушение прав доступа к чтению
Доброго времени суток! Возникла проблема в это коде. Компилятор выдает ошибку о нарушении прав доступа к чтению: void FindRepeat(char**...

Нарушения прав доступа к чтению (работа с файлами)
Пробую реализовать запись в файл: #define _CRT_SECURE_NO_WARNINGS #include &lt;iostream&gt; #include &lt;string&gt; using namespace std; ...

ООП c++ ошибка доступа
Всем привет,проблема с файлами,после того как написал код и раскинул его по файлам(в rectangle.cpp и rectangle hpp) пропал доступ к...

13
nd2
3438 / 2817 / 1249
Регистрация: 29.01.2016
Сообщений: 9,427
23.07.2017, 23:34
Лучший ответ Сообщение было отмечено anapshy как решение

Решение

Цитата Сообщение от anapshy Посмотреть сообщение
C++
1
obj = new B();
Значение не сохранится, по ссылке указатель передавай.
0
 Аватар для anapshy
531 / 272 / 220
Регистрация: 14.11.2016
Сообщений: 1,052
23.07.2017, 23:56  [ТС]
nd2, спасибо решил проблему void menu(Toy *&obj) {}. Думал, что изменится Т.е. по указателю просто так нельзя передавать пустые статические указатели на базовый тип для изменения динамического типа (искл. если статические указатели на базовый тип уже содержат динамический тип) ?
0
nd2
3438 / 2817 / 1249
Регистрация: 29.01.2016
Сообщений: 9,427
24.07.2017, 00:42
Цитата Сообщение от anapshy Посмотреть сообщение
Т.е. по указателю просто так нельзя передавать пустые статические указатели на базовый тип для изменения динамического типа (искл. если статические указатели на базовый тип уже содержат динамический тип) ?
Базовый или не базовый, динамический или статический - это, к данному случаю, отношения не имеет: передаёшь по знанчению, значит в функции изменяется копия, а не оригинал, чтобы изменялся оригинал нужно передавать по ссылке.
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,816
24.07.2017, 00:43
Цитата Сообщение от anapshy Посмотреть сообщение
Т.е. по указателю просто так нельзя передавать пустые статические указатели на базовый тип для изменения динамического типа (искл. если статические указатели на базовый тип уже содержат динамический тип) ?
Конечно можно:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
void set_memory(A ** obj)
{
///......
}
 
int main()
{
    A *a(NULL);
    set_memory(&a);
//.....
 
    delete a;
}
Что для вас в указателе такого магического? Эта переменная подчиняется тем же законам, что и остальные.
Ты же вот когда пишешь такой код:
C++
1
2
3
4
5
6
7
8
9
10
void foo(int a)
{
    a = 10;
}
int main()
{
    int v = 5;
    foo(v);
 //.....
}
не ждешь, что v после вызова foo станет равна 10?
Такая же ситуация и у тебя в коде, пока ты указатель передаешь по значению, в функцию попадает его копия. Изменение значения указателя внутри функции - это изменение его копии. И, чтобы избежать этого, как и в случае с int (и любым другим типом), передавать указатель надо либо по указателю, либо по ссылке, о чем, собственно, и сказали выше.
Хватит искать магию там, где ее нет
1
 Аватар для anapshy
531 / 272 / 220
Регистрация: 14.11.2016
Сообщений: 1,052
24.07.2017, 10:09  [ТС]
DrOffset, nd2, вот теперь вы меня точно запутали...
1) А как же тогда передаем одномерные массивы (int *a(new int[n]);) в функции void foo(int *arr) { a[0] = 1; ...; a[n-1] = n; }.
В функцию тоже попадает копия? Но ведь мы можем изменить значение в этом массиве, и оно отразится на том который передали в функцию.
2) А как же следующий код ниже? ..всё прекрасно работает:
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
#include <iostream>
#include <string>
#include <conio.h>
 
class A
{
protected:
    std::string str;
public:
    A(void) : str("None") {};
    virtual ~A(void) = default;
    void setStr(const std::string &_s)
    {
        str = _s;
    }
    virtual void test(void) = 0;
};
 
class B final : public A
{
public:
    B(void) : A() {};
    virtual ~B(void) = default;
    void test(void) override
    {
        std::cout << "B: " << this->str << std::endl;
    }
};
 
class D final : public A
{
public:
    D(void) : A() {};
    virtual ~D(void) = default;
    void test(void) override
    {
        std::cout << "D: " << this->str << std::endl;
    }
};
 
void set_memory(A *obj)
{
    std::cout << "Press key '1'" << std::endl;
    while (true)
    {
        switch (_getch())
        {
        case '1':
            delete obj;
            obj = new B();
            break;
        default:
            continue;
        }
        break;
    }
}
 
int main(void)
{
    A *a(new D());
    set_memory(a);
    std::string str("text");
    a->setStr(str); /* Выведет>>> B: text  */
    a->test();
    delete a;
    _getch();
    return EXIT_SUCCESS;
}
0
Любитель чаепитий
 Аватар для GbaLog-
3745 / 1801 / 566
Регистрация: 24.08.2014
Сообщений: 6,020
Записей в блоге: 1
24.07.2017, 10:50
Цитата Сообщение от anapshy Посмотреть сообщение
А как же тогда передаем одномерные массивы (int *a(new int[n]);)
это не одномерный массив.
Цитата Сообщение от anapshy Посмотреть сообщение
в функции void foo(int *arr) { a[0] = 1; ...; a[n-1] = n; }.
и что? a как указывал на начало блока памяти, так и указывает, а в этом блоке что-то изменяется.
в случае с приравниванием работает всё совершенно иначе:
C++
1
2
3
4
5
6
7
8
9
10
void foo(int * arr)
{
    arr = new int[1];
}
 
int main()
{
    int * arr = nullptr;
    foo(arr);
}
arr в main указывает на nullptr, после того, как мы передали его по значению в функцию foo, он изменился, то есть если раньше он скопировался и так же указывал на nullptr, то теперь он может указывать куда угодно, а arr в функции main до сих пор указывает на nullptr.

Цитата Сообщение от anapshy Посмотреть сообщение
..всё прекрасно работает
это UB.
работает по случайности.
у меня, например, выдало: Invalid memory reference (SIGSEGV).
после того, как я добавил между строчками 49 и 50: A * a = new D(); delete a;.
1
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,816
24.07.2017, 12:30
Цитата Сообщение от anapshy Посмотреть сообщение
А как же тогда передаем одномерные массивы (int *a(new int[n]) в функции void foo(int *arr) { a[0] = 1; ...; a[n-1] = n; }.
В функцию тоже попадает копия? Но ведь мы можем изменить значение в этом массиве, и оно отразится на том который передали в функцию.
Мы передаем никакой не массив, а указатель. Указатель, адрес в нем содержащийся - копируется. Но в функции мы меняем не адрес. В функции мы меняем значение по адресу. Это тоже самое, что в первом примере поста #5. Только тут у тебя указываемый тип - int, а там - указатель. И разницу между массивами и указателями надо обязательно знать, чтобы не путаться еще больше.

Цитата Сообщение от anapshy Посмотреть сообщение
C++
1
obj = new B();
Это изменение значения копии указателя.
Цитата Сообщение от anapshy Посмотреть сообщение
C++
1
delete obj;
Это освобождение памяти, используя копию указателя.
Цитата Сообщение от anapshy Посмотреть сообщение
C++
1
a->setStr(str);
Это доступ к освобожденной памяти после вызова set_memory. На указатель a в main присваивание нового адреса внутри set_memory не отразилось (внимательно вспоминаем о чем писалось выше), зато после delete адрес, который в а содержался - "протух" (нет, он не изменился, это легко увидеть, если распечатать все адреса). Но теперь, память, на которую он по-прежнему указывает, освобождена, а доступ к такой памяти - это UB.
1
 Аватар для anapshy
531 / 272 / 220
Регистрация: 14.11.2016
Сообщений: 1,052
24.07.2017, 12:55  [ТС]
DrOffset, теперь всё понятно
0
24.07.2017, 13:19

Не по теме:

anapshy, как вы пишите код в строке?

Цитата Сообщение от anapshy Посмотреть сообщение
(int *a(new int[n]);)
типо как здесь?

0
 Аватар для anapshy
531 / 272 / 220
Регистрация: 14.11.2016
Сообщений: 1,052
24.07.2017, 13:33  [ТС]
Azazel-San, int *a(new int[5]); / int *a = new int[5];
А в чём разница то?
0
24.07.2017, 13:41

Не по теме:


anapshy, я не об этом, ну вот вокруг int *a(new int[5]); такая рамка, вы какие теги использовали для "int *a(new int[5]);" ?а все понял

0
 Аватар для anapshy
531 / 272 / 220
Регистрация: 14.11.2016
Сообщений: 1,052
24.07.2017, 13:43  [ТС]
Azazel-San, ааа... [INLINE][/INLINE]
1
зомбяк
 Аватар для TRam_
1585 / 1219 / 345
Регистрация: 14.05.2017
Сообщений: 3,940
24.07.2017, 14:03
Цитата Сообщение от anapshy Посмотреть сообщение
А в чём разница то?
Никакой разницы нет, кроме разве что того, что вторая запись более удобная для восприятия.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
24.07.2017, 14:03
Помогаю со студенческими работами здесь

Модификаторы доступа, ооп
class Person { } class User : Person { } class Director : Person {

MVC. ООП. Разграничение прав доступа
Здравствуйте. Посоветуйте, как организовать разграничение прав доступа к экшенам контроллера. Проверять доступность на уровне роутера,...

Просветите на тему ООП (особенности применения модификаторов доступа)
У меня вызывает небольшое недоумение, конечно, из-за моего недостатка знаний в области программирования один момент. Вот есть, например,...

ООП: сделать минимум 3 уровня наследования со всеми модификаторами доступа
Пишу задание для понимая ООП, но все-таки есть у меня мысль, что я делаю все неправильно. В задании необходимо сделать минимум 3...

Нарушение доступа
void FilterStamp() { char ch; cout&lt;&lt;&quot;Введите Да или Нет: &quot;; scanf_s(&quot;%s&quot;,ch); cout&lt;&lt;endl; l1=first; while(l1!=0)...


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

Или воспользуйтесь поиском по форуму:
14
Ответ Создать тему
Новые блоги и статьи
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. Сканируйте QR-код на мобильном. Вращайте камеру одним пальцем,. . .
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip Сканируйте QR-код на мобильном и вы увидите, что появится джойстик для управления главным героем. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru