为什么此代码会引发读取访问冲突?

问题描述

我需要帮助弄清楚为什么这段代码会引发读取访问冲突

代码在数组的第4个值处引发读取访问冲突,这是在我在第7和8行中添加动态内存分配时开始发生的

ProceduralStories.cpp

#include <iostream>

#include "ProceduralStories.h"

void main()
{
    Object* _objects = NULL;
    _objects = new Object[10];

    for (int i = 0; i < 10; i++)
    {
        Object object = Object
        {
            object.position = glm::vec3 {rand() % 1000 + 1,rand() % 1000 + 1,rand() % 1000 + 1},object.mesh = i
        };

        _objects[i] = object;
    }

    Location location1
    {
        location1.position = glm::vec3 {0.0f,0.0f,0.0f},};

    for (int i = 0; i < 10; i++)
    {
        location1.objects[i] = _objects[i]; //Throws a Read Access Violation at the 4th value of the array,so [3]
        std::cout << location1.objects[i].mesh << ",(" << location1.objects[i].position.x << ',' << location1.objects[i].position.y << ',' << location1.objects[i].position.z << ')' << std::endl;
    }
}

ProceduralStories.h


#include "glm/vec3.hpp"

struct Object
{
    glm::vec3 position;
    int mesh;
};

struct Location
{
    glm::vec3 position;
    Object objects[];
};

解决方法

您从未为objects[]分配任何空间。因此,当您尝试将location1.objects[i]设置为某个值时,就是在写入尚未分配的空间。

如果您确实分配了空间,请告诉我分配空间的位置和数量。你做不到。

,

请不要这样做。

花时间,学习编写RAII课。

如果您编写新的内容,则必须调用delete,否则会在较大的项目中泄漏内存。

当对象超出范围时,析构函数将为您执行此操作。但是在这种情况下,您将调用默认的析构函数,该默认析构函数仅调用子析构函数,而指针不会自行清除。

#include<iostream>
struct loc{
    int pos;
    int*obj;
};
void run();
int main(){
   run();
   return 0;
}
void run()
{
    using namespace std;
    loc t{ 42,new int[10]};

    cout<<t.pos<<endl;

    t.obj[0] = 5;
    t.obj[9] = 3;

    for(int i = 0; i < 10; i++)
    {
        cout<<t.obj[i]<<endl;
    }
    delete[] t.obj;
}

编辑:我有责任提供更好的选择。

我不一定认为这是最好的解决方案,但是正如我提到的RAII,我会给你一些东西。

#include<iostream>
class loc{
 public:
    int pos;
 private:
    unsigned long size;
    int*obj;
 public:
    loc(): pos{0},size{},obj{nullptr}
    {
    }
    loc(int pos,unsigned long size):pos{pos},size{size}
    {
        obj = new int[size];
    }
    loc(loc&)=delete;
    loc(loc&&)=delete;
    loc operator=(loc&)=delete;
    loc operator=(loc&&)=delete;
    ~loc()
    {
        delete[] obj;
    }
    int&operator[](unsigned long index)
    {
        if(index > size) throw std::out_of_range
        ( "Index "
        + std::to_string(index)
        + " excededs allocated size "
        + std::to_string(size)
        );
        return obj[index];
    }


};
void run()
{
using namespace std;
    loc t{ 42,10};

    cout<<t.pos<<endl;

    t[0] = 5;
    t[9] = 3;

    for(int i = 0; i < 10; i++)
    {
        cout<<t[i]<<endl;
    }
    // destructor deleate memory for you.
}

请仔细阅读副本移动分配和移动分配构造函数以及何时使用它们。由于这不是个人原因,因此超出了问题的范围。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...