0

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);

}
kiala11
  • 11
  • 3
  • 1
    What is Element? I suspect it isn't a POD. – Eljay May 10 '22 at 02:45
  • A [mcve] would be helpful in diagnosing the issue. – Retired Ninja May 10 '22 at 02:53
  • Element is a very simple struct – kiala11 May 10 '22 at 02:54
  • 1
    "very simple" is not an adequate description. Add the definition to your question. – Retired Ninja May 10 '22 at 03:03
  • I've added the definition to the question. I'm trying to make the minimal reproducible example that you've sent, but it's taking some time because i'm not exactly sure whats causing the problem. I'll edit into the question when I get it, though – kiala11 May 10 '22 at 03:06
  • 3
    what does idx(x,y) do? if youre accessing out of bounds youd probably get that error – Borgleader May 10 '22 at 03:06
  • idx(x,y) just gets the index of x and y in the array. I've also got a small example that that gives the error when debugging, i'll edit into the question. – kiala11 May 10 '22 at 03:10
  • I *think* you have an incorrect indirection. And its partially obscured by specifying the array size in the function signature (which decays anyway afaik). In your minimal example, if directly after you allocate your Broken array, you do `borked[x].x;` you'll see that it compiles, but notice that in your function you index the array and still use pointer syntax to get x. Theres a mismatch there and that's causing your crash. https://godbolt.org/z/h17xjsnqd see edited code for details (I dont crash with my edits) – Borgleader May 10 '22 at 03:21
  • To my knowledge, in a function signature void foo(Broken* bar[10]) is equivalent to void foo(Broken** bar) but you didnt allocate an array of pointers to Broken, you allocated an array of Broken, the & when passing it to the function is wrong, and so is the function signature. it should either be Broken bar[1000] or Broken* bar. – Borgleader May 10 '22 at 03:24
  • Borgleader, that solved my problem, thanks! I'm not sure how to mark it as solved, but i'll figure it out :) – kiala11 May 10 '22 at 03:33

1 Answers1

0

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.