【问题标题】:Access violation writing location error when i try to read from file当我尝试从文件中读取时,访问冲突写入位置错误
【发布时间】:2014-05-29 05:12:31
【问题描述】:

这是我写入文件的地方 ->

void Supermarket_Billing_System::Add_and_WriteNewProduct(Product P)
{
    ofstream fl;
    fl.open("ProductList", ios::out | ios::binary);
    fl.write((char *) &P, sizeof(P));
    fl.close();
}

这是我从文件中读取的地方 ->

void Supermarket_Billing_System::Read_DisplayProductFromProductList()
{
    Product P;
    int x;
    ifstream fp;
    fp.open("ProductList", ios::in);
    fp.seekg(0, ios::beg);
    fp.read((char *) &P, sizeof(P));
    x = P.GetProduct_qty();
    fp.close();
}

产品类看起来像这样 ->

class Product
{
private:
     long int Product_no;
     std::string Product_name;
     double Product_price;
     int Product_qty;
     double Product_tax;
     double Product_dis;

public:

    //Constructor
    Product();
    Product(long int, string, double, int, double, double);

    //All Getters methods
    long int GetProduct_no();
    string GetProduct_name();
    double GetProduct_price();
    int GetProduct_qty();
    double GetProduct_tax();
    double GetProduct_dis();

    //All Setters methods
    void SetProduct_no(long int);
    void SetProduct_name(string);
    void SetProduct_price(double);
    void SetProduct_qty(int);
    void SetProduct_tax(double);
    void SetProduct_dis(double);

    void Accept_Product();
    void Accept_ProductForBilling();
    void Display_Product();
};

当我尝试通过调用 Read_DisplayProductFromProductList() 从文件中读取时,它给了我错误 ->

Supermarket_Billing_System.exe 中 0x6803ad54 (msvcp100d.dll) 处的未处理异常:0xC0000005:访问冲突写入位置 0xfeeefeee。

【问题讨论】:

    标签: c++ visual-c++


    【解决方案1】:

    由于std::string 成员,您的Product 类不可轻易复制;您没有写入 Product_name 在您的 write 方法中保存的实际字符串,只是 std::string 的二进制表示,并且当您读取时,内部字符串指针几乎肯定会指向无效位置。尝试执行非平凡可复制类的按字节复制的任何一种方式都是未定义的行为。

    当您打开文件进行阅读时,您还没有传递binary 标志

    fp.open("ProductList", ios::in);
    

    如果您正在读取的文件中有任何 \r\n (0x0A 0x0D) 序列,这将导致 Windows 出现问题。

    您需要为您的字符串使用char 数组,或者手动处理每个成员的序列化。最简单的方法是使用stream friend functions 将您的对象写入纯文本文件

    【讨论】:

      【解决方案2】:

      我相信你不应该像 POD(普通旧数据)那样读入 std::string。 std::string Product_name 是您的 Product 类的成员,当您从流中读取时,它可能会破坏字符串。

      同样,你不应该这样写std::string(作为Product的一部分)。

      【讨论】:

        【解决方案3】:

        当我在 gSOAP 客户端中使用 ofstream 对文件进行写入操作时,我遇到了类似的问题。但是,当我切换到 FILE (stdio.h) 和 fwrite() 时,访问冲突错误消失了!

        【讨论】:

          【解决方案4】:

          可能是因为打开文件错误。您可以打印返回值以查看它是否为 NULL。 当你编译你的代码时。

          注意警告信息。有时,它可能只是在编译时发出警告,但在运行时却崩溃了。

          【讨论】:

          • 你好,尹洁!欢迎来到 stackoverflow(好吧,我猜你已经潜伏了一段时间)。虽然在一般情况下您的答案可能有误,也可能没有错,但对于这个特定问题,已经有解决原始发帖人问题的答案。您可能会发现阅读一些关于回答问题的页面stackoverflow.com/help/answering 会有所帮助,例如stackoverflow.com/help/how-to-answer。如果您还有其他问题,请尝试stackoverflow.com/help。祝你好运!
          • 我所说的是错误的另一种情况当我尝试从文件中读取时访问冲突写入位置错误。因为我得到了这个错误并且没有在stackoverflow中找到答案。我认为答案有贡献,可以让社区变得更好。我们实际上不需要让它太死板。任何贡献都是可以接受的,对吧?其他人可能会和我到达同一个空间并从中找到答案。那是我的。如果你禁止我认真回答问题,你会影响我对它的热情。
          • 问题标题只是一个标题。问题细节是需要回答的。如果您没有找到堆栈溢出问题的答案,但您找到了答案,您可以提出并回答您自己的问题,让未来的搜索从您共享的内容中受益,同时保留当前问题的答案专注于当前的细节。如果您决定这样做,详细说明以防止将其标记为重复是有帮助的。我希望这会有所帮助!
          • 嗨,hlongmore!我接到你了。将来我会针对相同的标题和不同的具体错误创建问题。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-08-12
          • 1970-01-01
          • 2020-09-04
          相关资源
          最近更新 更多