Unhandled Exception: System.AccessViolationException: Attempted to read or write protected memory. This is...

Hi,

I am getting an error when I run my program.

the error is...

Unhandled Exception: System.AccessViolationException: Attempted to read or write protected memory. This is often indication that other memory is corrupt.

I did some research and it seems this code is the problem.

// Create the Bitplanes
int* Bitplane0__ROW = new int[1000];
int* Bitplane1__ROW = new int[1000];
int* Bitplane2__ROW = new int[1000];
int* Bitplane3__ROW = new int[1000];

if I lower the values it runs without errors but not with the above values.

My program creates png images from those Bitplanes which are read from a file.

I tried to simplify my code to pin point the problem code.

I am expecting to write a 256 x 256 png image using the color data stored in those bitplanes.

Thanks in advance.
Use a debugger to see which line of code where the access violation is happening.
The error message doesn't seem to be for C++. What language/compiler are you using? Is this C++/cli?

If it works Ok when the size of the arrays are lowered, it could be that you are exceeding the stack size. Where in the program are these arrays defined? Try making them global at the top of the program.
Last edited on
@seeplus Dynamically allocated arrays are not stored on the stack.

I'm not sure the problem has anything at all to do with the arrays. Maybe something else is at fault and a change in array size just happens to trigger an access violation because things are laid out differently in memory. Using valgrind or an address sanitizer might help.
Last edited on
You have to check all the prior memory allocations in your program to make sure you're not overflowing / underflowing / use after free / double free / etc.

1
2
int *p = new int[10];
p[10] = 0;  // oops 

The time it takes for this to show up as an issue can be anywhere between microseconds and years.

And it will usually manifest itself as tanking some completely unrelated code such as
 
int* Bitplane0__ROW = new int[1000];


> This is often indication that other memory is corrupt.
Exactly.

You need to look back through your code execution path that led to this point in the code, and see if you're doing anything suspect with any dynamically allocated memory.
@seeplus Dynamically allocated arrays are not stored on the stack.


Whops! You are quite right. I think I'll chalk that down to 'having a senior moment'!
Thanks everyone for your replies!

Stack overflow suggest this below code.
I no longer get any errors but I have one other issue that breaks the program... :(

1
2
3
4
5
6
7
8
9
10
11
     // Create the Bitplanes
    //int* Bitplane0__ROW = new int[1000];
    //int* Bitplane1__ROW = new int[1000];
    //int* Bitplane2__ROW = new int[1000];
    //int* Bitplane3__ROW = new int[1000];

// This works
    std::vector<int> Bitplane0__ROW(10000);
    std::vector<int> Bitplane1__ROW(10000);
    std::vector<int> Bitplane2__ROW(10000);
    std::vector<int> Bitplane3__ROW(10000);


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
 if (p > 119 && p < 128) //  
            {
                // This Works
               // x_coord = 0x86 * 4;
               // y_coord = 0x80; 

                
                char oDataL[0x100]; // Sprite buffer
                ifstream inFileL;
                inFileL.open("C:\\Users\\Chris\\Desktop\\file.bin", ios::binary); // Note. this opens a binary streem. This is needed. cuzz the program was using 0x1a values as a Substitute AscII charter which halts the program/Using it as End Of File.
                inFileL.seekg(0xE48A1, 1); // Seek to the current sprite coordinate location.
                inFileL.read(oDataL, 0x100);
                inFileL.close();

// this does not.
                x_coord = oDataL[1] *4; 
                y_coord = oDataL[2]; 


            }


The idea is I read tiles from a file and read each tiles location.
If I manually specify the X/Y location it works but not when I read the bytes from the file.
Some byes work but others do not.

The bytes in question are...

0x86

and

0x80

for some reason they aren't reading correctly
Last edited on
Try unsigned char, maybe you're getting negative values when > 0x79.
 
unsigned char oDataL[0x100];

You might have to cast oDataL to char in the read:
 
inFileL.read((char*)oDataL, 0x100);

Last edited on
Awesome thanks Dude! That did the trick!
So I was getting negative values then?
I would never had figured it out on my own. :'(

btw there is a typo in your example.... forgot the "*". ;)


Below code now works.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
if (p > 119 && p < 128) //  
            {
               
                unsigned char oDataL[0x100];

                // Sprite buffer
                ifstream inFileL;
                inFileL.open("C:\\Users\\Chris\\Desktop\\file.bin", ios::binary); // Note. this opens a binary streem. This is needed. cuzz the program was using 0x1a values as a Substitute AscII charter which halts the program/Using it as End Of File.
                inFileL.seekg(0xE48A1, 1); // Seek to the current sprite header location.
                inFileL.read((char*)oDataL, 0x100);
                inFileL.close();

                x_coord = oDataL[1] *4; 
                y_coord = oDataL[2]; 


            }
> // This works

No, you rearranged the deckchairs on the Titanic.

All you did was change the order and layout of all the memory allocations in the pool, such to avoid whatever is currently wrong with the pool.

You didn't make the iceberg go away.
You just found a chair to sit in for the moment where you can't see it.

Basically, every new change you make to the code is rolling the dice as to whether the problem will come back.

Ah I see. That makes sense. Sorry I'm a noob.

What do you suggest I do so I can better understand the code?


My guess is that your jpg imaga has WAY MORE pixels than a 1000. So calculate the amount of memory before you allocate your memory (make your vectors). So show more of your code because the problem is not directly in here, but where you access the pixels. Side note you're probably better of not allocate memory for each single line, allocate memory for the whole plane (and calculate offsets in that yourself)



Thanks.
Stack overflow suggest this

Using a dynamic container, a vector, instead of a fixed sized array is a good idea for a couple of reasons. A vector automatically manages the memory used.

If you are going to use a vector you could instantiate one without any preallocated elements and push back what you read from the file on demand. So you don't need to know how many planes/pixels get read, the vector grows as needed on demand.

https://en.cppreference.com/w/cpp/container/vector/vector
https://en.cppreference.com/w/cpp/container/vector/push_back

Your vector automatically knows what its size is, it could be less or greater than your expected 1000 elements.

With a vector there are two ways to access an element. operator[] and the at member function. The at member function is a bit slower than operator[] because at performs bounds checking.

https://en.cppreference.com/w/cpp/container/vector/at

One (minor) drawback from not preallocating a vector's size on creation is the process of adding elements is slower than assigning elements in a presized vector. But not horrendously slower and expensive.

Hi, George.

Thank you for your guidance.
I will review the links you provided.
For the basics on fixed and dynamic containers there's 2 lessons at Learn C++ you might want to peruse. Chapter 16 for dynamic containers (std::vector) and chapter 17 for fixed size arrays (std::array and C-style arrays)

https://www.learncpp.com/cpp-tutorial/introduction-to-containers-and-arrays/

https://www.learncpp.com/cpp-tutorial/introduction-to-stdarray/

The rest of Learn C++ might be a good refresher for other parts of the language as well.
so salem c is correct. The problem came back. It seems a bit random, some times when i change the code the error message comes back. other times it goes away.

Would it help if I link to the code. Its quite long and inefficient.

thanks.
Registered users can post here. Sign in or register to post.