Home > Software design >  Exception thrown at 0x00007FF63C04254B in Elements.exe: 0xC0000005: Access violation reading locatio
Exception thrown at 0x00007FF63C04254B in Elements.exe: 0xC0000005: Access violation reading locatio

Time:05-10

I have a couple of arrays in my main.cpp, as seen here:

...
Element* screen, *buffer;
screen = new Element[GAME_WIDTH * GAME_HEIGHT];
buffer = new Element[GAME_WIDTH * GAME_HEIGHT];
memset(screen, 0, GAME_WIDTH * GAME_HEIGHT * sizeof(Element));
memset(buffer, 0, GAME_WIDTH * GAME_HEIGHT * sizeof(Element));
...

And, in a my elem.cpp there is a function that uses one of these arrays:

void drawElements(Element* screen[GAME_WIDTH * GAME_HEIGHT]) {
    for (int x = 1; x < GAME_WIDTH - 2; x  ) {
        for (int y = 1; y < GAME_HEIGHT - 2; y  ) {
            std::cout << screen[idx(x, y)]->id << std::endl; //Temporary, problem here
        
        }
    }
}

While all this should do is just print 0 a bunch of times currently, instead it throws the exception shown in the title of this question when debugged, right where the comment is in the elem.cpp code snippet. I've read that this can be caused by not initializing an object, but I think that they are initialized, as they are created and all set to 0 in the main.cpp code snippet.

I'm fairly new to pointers and such, so it is entirely possible that this problem arises from some simple quirk of pointers and references, but i'm not quite sure what is going on.

Here is the definition of the Element struct:

struct Element {
    int id;
    float lifetime;
    int density;
};

And for he who requested it, here is my attempt at a minimal reproducible example of my problem, it throws the same exception when ran through the VC debugger.

struct Broken {
    int x = 20;
};
void doSomething(Broken* borked[10000]) {
    for (int x = 1; x < 10000 - 1; x  ) {
        std::cout << borked[x]->x << std::endl; //Throws exception here
    }
}
int main()
{
    Broken* borked;
    borked = new Broken[10000];
    memset(borked, 0, 10000 * sizeof(Broken));

    doSomething(&borked);

}

CodePudding user response:

The problem is that your function signature is incorrect and you had to add an extra & when passing the array to the function to compensate (i.e. to get it to compile).

In your minimal examble, you have allocated is an array of Broken, but your function signature is expecting an array of Broken*.

void doSomething(Broken* borked[10000]) { is equivalent to: void doSomething(Broken** borked) { see the first answer: Passing Arrays to Function in C

To compensate what you did is doSomething(&borked) but really the fix is to leave it as doSomething(borked); and change the function signature to: void doSomething(Broken* borked) { because that is what you actually have.

CodePudding user response:

what is declared "single" is a single pointer.

the variable "screen" declared in "drawElements" is a double pointer, not a single pointer. also, when accessing a variable in an array, instead of using the operator->, operator. must be used.

Element* screen, *buffer; // <= definition single pointer
screen = new Element[GAME_WIDTH * GAME_HEIGHT]; 

void drawElements(Element* screen[GAME_WIDTH * GAME_HEIGHT]){ // <= this mean double pointer
    for (int x = 1; x < GAME_WIDTH - 2; x  ) {
        for (int y = 1; y < GAME_HEIGHT - 2; y  ) {
            std::cout << screen[idx(x, y)]->id << std::endl; //Invalid variable access
        
        }
    }
}
// wrong call element
std::cout << screen[idx(x, y)]->id << std::endl;

// correct call element
std::cout << screen[idx(x, y)].id << std::endl;

change it in the following way :D

void drawElements(Element* screen) {
    for (int x = 1; x < GAME_WIDTH - 2; x  ) {
        for (int y = 1; y < GAME_HEIGHT - 2; y  ) {
            std::cout << screen[idx(x, y)].id << std::endl; //Temporary, problem here
        
        }
    }
}

another this

void drawElements(Element screen[GAME_WIDTH * GAME_HEIGHT]) {
    for (int x = 1; x < GAME_WIDTH - 2; x  ) {
        for (int y = 1; y < GAME_HEIGHT - 2; y  ) {
            std::cout << screen[idx(x, y)].id << std::endl; //Temporary, problem here
        
        }
    }
}

ps. Why did you use a single array in this implementation? In this case, a double array is usually used to separate the width and height.

  •  Tags:  
  • c
  • Related