簡體   English   中英

C++ 異常“訪問沖突讀取位置”

[英]C++ Exception "Access violation reading location"

#include <iostream>    
#include <fstream>     
using namespace std;

struct review {
    string text;
    string date;
};

void getRegistry(int i) {
    review* reg = new review;
    ifstream file;
    file.open("test.txt", ios::binary);
    if (file) {
        file.seekg(i * sizeof(review), ios::beg);
        file.read(reinterpret_cast<char*>(reg), sizeof(review));
        cout << reg->text;
        file.close();
    }
    delete reg;
}

void generateBinary()
{
    ofstream arq("test.txt", ios::binary);
    review x;
    x.text = "asdasdasd";
    x.date = "qweqweqwe";
    for (int i = 1; i <= 1000000; i++)
    {
        arq.write(reinterpret_cast<const char*>(&x), sizeof(review));
    }

    arq.close();
}


int main() {

    generateBinary();
    getRegistry(2);
    
    return 0;
}

你好,我正在嘗試制作一個程序,它將幾個“評論”寫入二進制文件,然后讀取某個注冊表。 該程序似乎可以工作,但最后總是拋出異常:“在 trabalho.exe 中在 0x00007FF628E58C95 拋出異常:0xC0000005:訪問沖突讀取位置 0xFFFFFFFFFFFFFFFF。” 我該如何解決這個問題? 謝謝!

運算符sizeof (review)不返回包含字符串的長度。 這是因為字符串 class 包含指向真實字符串的指針,這些指針位於動態分配的 memory 的單獨位置。 您應該明確使用字符串的長度,並明確寫入字符串而不是 class。 從文件中讀取也是如此。 首先閱讀字符串,然后屬性進行審查。

問題是您無法按照自己的方式讀取/寫入std::string對象。 std::string保存指向存儲在 memory 其他地方的可變長度字符數據的指針。 您的代碼沒有考慮到這一事實。

為了能夠以您嘗試的方式在對象文件中查找特定 object,您必須使用固定大小的對象,例如:

#include <iostream>    
#include <fstream> 
#include <cstring>    
using namespace std;

struct review {
    char text[12];
    char date[12];
};

void getRegistry(int i) {
    ifstream file("test.txt", ios::binary);
    if (file) {
        if (!file.seekg(i * sizeof(review), ios::beg)) throw ...;
        review reg;
        if (!file.read(reinterpret_cast<char*>(&reg), sizeof(reg))) throw ...;
        cout << reg.text;
    }
}

void generateBinary()
{
    ofstream arq("test.txt", ios::binary);
    review x = {};
    strncpy(x.text, "asdasdasd", sizeof(x.text)-1);
    strncpy(x.date, "qweqweqwe", sizeof(x.date)-1);
    for (int i = 1; i <= 1000000; ++i) {
        if (!arq.write(reinterpret_cast<char*>(&x), sizeof(x))) throw ...;
    }
}

int main() {
    generateBinary();
    getRegistry(2);
    return 0;
}

否則,要處理可變長度數據,您需要(反)序列化每個 object,例如:

#include <iostream>    
#include <fstream> 
#include <cstdint>    
using namespace std;

struct review {
    string text;
    string date;
};

string readStr(istream &is) {
    string s;
    uint32_t len;
    if (!is.read(reinterpret_cast<char*>(&len), sizeof(len))) throw ...;
    if (len > 0) {
        s.resize(len);
        if (!is.read(s.data(), len)) throw ...;
    }
    return s;
}

void skipStr(istream &is) {
    uint32_t len;
    if (!is.read(reinterpret_cast<char*>(&len), sizeof(len))) throw ...;
    if (len > 0) {
        if (!is.ignore(len)) throw ...;
    }
}

void writeStr(ostream &os, const string &s) {
    uint32_t len = s.size();
    if (!os.write(reinterpret_cast<char*>(&len), sizeof(len)) throw ...;
    if (!os.write(s.c_str(), len)) throw ...;
}

review readReview(istream &is) {
    review r;
    r.text = readStr(is);
    r.date = readStr(is);
    return r;
}

void skipReview(istream &is) {
    skipStr(is);
    skipStr(is);
}

void writeReview(ostream &os, const review &r) {
    writeStr(is, r.text);
    writeStr(is, r.date);
}

void getRegistry(int i) {
    ifstream file("test.txt", ios::binary);
    if (file) {
        while (i--) skipReview(file);
        review reg = readReview(file);
        cout << reg.text;
    }
}

void generateBinary()
{
    ofstream arq("test.txt", ios::binary);
    review x;
    x.text = "asdasdasd";
    x.date = "qweqweqwe";
    for (int i = 1; i <= 1000000; ++i) {
        writeReview(arq, x);
    }
}

int main() {
    generateBinary();
    getRegistry(2);
    return 0;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM