Нарушение прав доступа при попытке создать класс с широкой строкой - PullRequest
0 голосов
/ 15 ноября 2018

Я создаю код, который должен прочитать журнал отладки, разобрать журнал и активировать Google текст-в-речь, который даст информацию об игре, которая выплевывает его.

Журнал имеет кодировку UTF-8, поэтому я использую широкие строки в коде, код компилируется и анализирует строки очень хорошо, пока я не попытаюсь создать объект класса.

Тогда я получаю нарушение прав доступа:

'CMakeProject1.exe' (Win32): Loaded 'C:\Users\eirik\CMakeBuilds\e36ef523-902d-0932-93cd-2201bbe1e731\build\x64-Release\CMakeProject1\CMakeProject1.exe'. Symbols loaded.
'CMakeProject1.exe' (Win32): Loaded 'C:\Windows\System32\ntdll.dll'. Cannot find or open the PDB file.
'CMakeProject1.exe' (Win32): Loaded 'C:\Windows\System32\kernel32.dll'. Cannot find or open the PDB file.
'CMakeProject1.exe' (Win32): Loaded 'C:\Program Files\AVAST Software\Avast\x64\aswhooka.dll'. Cannot find or open the PDB file.
'CMakeProject1.exe' (Win32): Loaded 'C:\Windows\System32\KernelBase.dll'. Cannot find or open the PDB file.
'CMakeProject1.exe' (Win32): Loaded 'C:\Windows\System32\ucrtbase.dll'. Cannot find or open the PDB file.
'CMakeProject1.exe' (Win32): Loaded 'C:\Windows\System32\msvcp140.dll'. Cannot find or open the PDB file.
'CMakeProject1.exe' (Win32): Loaded 'C:\Windows\System32\vcruntime140.dll'. Cannot find or open the PDB file.
The thread 0x4174 has exited with code 0 (0x0).
Exception thrown at 0x00007FF7FBDA92B3 in CMakeProject1.exe: 0xC0000005: Access violation reading location 0x0000000000000000.

Значения Varibale непосредственно перед сбоем

#include <string>
#include <chrono>
#include <thread>
#include <iostream>
#include <fstream>
#include <windows.h>
#include <cstdlib>
#include <vector>
#include <map>
#include <thread>
#include <mutex>
#include <locale>
#include <codecvt>

std::wstring line;
std::wstring passed_string;
std::string path = "c:\\Users\\OptoCloud\\AppData\\LocalLow\\Game\\output_log.txt";

std::wifstream file(path, std::ios::binary);

class Create_Object
{
public:
    Create_Object();
    Create_Object(std::wstring passed_string);
    std::wstring Object_string = 0;
};
Create_Object::Create_Object() {}
Create_Object::Create_Object(std::wstring passed_string)
{
    Object_string.reserve(passed_string.length());
    Object_string = passed_string;
}

std::map<std::wstring, Create_Object> objectlist;

int main()
{
    while (true)
    {
        file.open(path.data());
        if (file.is_open())
        {
            while (std::getline(file, line))
            {
                if (line.find(L"DELIMITER1") != std::string::npos)
                {
                    passed_string = line.substr(line.find(L"DELIMITER1"), line.find(L"DELIMITER2"));
                    objectlist[passed_string] = Create_Object(passed_string); ///////////////////////POINT OF CRASH////////////////////////////////
                }
                file.close();
                break;
            }
        }
    }
    return 1;
}

(Edited)

1 Ответ

0 голосов
/ 15 ноября 2018

Проблема с кодом заключается в том, что член std::wstring создается со значением 0 здесь, в вашем Create_Object классе:

std::wstring Object_string = 0;

Создание std::basic_string (что std::wstringосновано на) с 0 - неопределенное поведение.Происходит то, что 0 неявно преобразуется в символьный указатель, поэтому будет вызван этот конструктор:

std::wstring(const wchar_t* p)

См. конструктор (5) здесь для std :: basic_string.

Этот конструктор предполагает, что переданный указатель не является нулевым, и указывает на завершенную нулем строку.Так как к нулевому указателю будет получен доступ, вы получите ошибку нарушения доступа.

Исправление к этому - просто избавиться от этой инициализации:

std::wstring Object_string;

Для дальнейшей демонстрации ошибки здесь небольшой пример, показывающий проблему .Удаление инициализации устраняет проблему .

...