Pointers with Images Help

I get a memory access violation when I run the below code. void createNewImage(int width, int height); this function deletes any current image data and creates a new image with the specified width/height and allocates the needed number of pixels dynamically. The new image contains four blocks with different color, red, blue, green, and black. I'm really having a lot of trouble with this one I cant get my head around images with pointers.

Thanks


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171

#include <iostream>
#include "image.h"


image::image() 
{
	pixels = NULL;
	width = 0;
	height = 0;
}

image::image(string filename) 
{
	pixels = NULL;
	width = 0;
	height = 0;
	loadImage(filename);
}

image::image(image &other)
{
	

}
image::~image()
{
	for (int i = 0; i < height; i++)
		delete[]this->pixels[i];
	delete[]this->pixels;
}

int image::getWidth()
{
	return this->width;
}

int image::getHeight()
{
	return this->height;
}

pixel** image::getPixels()
{
	return this->pixels;
}

void image::createNewImage(int width, int height)
{

	for (int i = 0; i < height; i++)
		delete[]this->pixels[i];
	delete[]this->pixels;

	//provide the code for this function
	pixel **p = new pixel*[width];

	for (int i = 0; i < width; i++)
		p[i] = new pixel[width];

	//for (int j = 0; j < height; j++)
		//p[j] = new pixel[height];



	for (int i = 0; i < width; i++)
	{

		for (int j = 0; j < height; j++)
		{

			p[i][j].red=255;
			p[i][j].blue=0;
			p[i][j].green = 0;
			
		}

	}
	this->pixels = p;
}







//-------------------------------------------Please do not touch the following functions---------------------------------
bool image::loadImage(string filename)
{
	if(pixels)
	{
		for(int i=0; i<height; i++)
			delete [] pixels[i];
		delete [] pixels;
		pixels = NULL;
		width = 0;
		height = 0;
	}
	
	CImage myImage;
	CString cs(filename.c_str());
	myImage.Load(cs);
	
	if(myImage.IsNull())
	{
		cout << "The requested image could not be loaded." << endl;
		return false;
	}
	if(myImage.GetBPP() != 24) 
	{
		cout << "The input image must be stored in the 8 bit RGB (24 bpp) colorspace." << endl;
		return false;
	}

	width = myImage.GetWidth();
	height = myImage.GetHeight();

	pixels = new pixel*[height];
	uchar* imageBuf = (uchar*)myImage.GetBits();
	int scanline = myImage.GetPitch();

	for (int j = 0; j < height; j++) 
	{
		pixels[j] = new pixel[width];	
		for (int i = 0; i < width; i++) 
		{
			pixels[j][i].red = imageBuf[j*scanline+i*3+2];
			pixels[j][i].green = imageBuf[j*scanline+i*3+1];
			pixels[j][i].blue = imageBuf[j*scanline+i*3];
		}
	}
	return true;
}

void image::pixelsToCImage(CImage* myImage)
{
	myImage->Create(width, height, 24, 0);
	if (myImage->IsNull()) {
		cout << "An error occured when creating a new image!" << endl;
		return;
	}

	uchar* imageBuf = (uchar*)myImage->GetBits();
	int scanline = myImage->GetPitch();
	for (int j = 0; j < height; j++) 
		for (int i = 0; i < width; i++) 
		{
			imageBuf[j*scanline+i*3] = pixels[j][i].blue;
			imageBuf[j*scanline+i*3+1] = pixels[j][i].green;
			imageBuf[j*scanline+i*3+2] = pixels[j][i].red;
		}
}

void image::saveImage(string filename) 
{
	if(!pixels)
	{
		cout << "No image data has been created to save! (The pixel buffer is empty)" << endl;
		return;
	}

	CImage myImage;
	pixelsToCImage(&myImage);

	CString cs(filename.c_str());
	myImage.Save(cs);

	return;
}
There's lots of code there, and without showing declarations of things--the declarations aren't irrelevant details, they're absolutely essential.

Looking from the top I saw this error. You should be using the height version of the loop.
1
2
3
4
5
6
7
8
	//provide the code for this function
	pixel **p = new pixel*[width];

	for (int i = 0; i < width; i++)
		p[i] = new pixel[width];

	//for (int j = 0; j < height; j++)
		//p[j] = new pixel[height]; 
.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#ifndef IMAGE
#define IMAGE

#include <atlimage.h>
#include <string>
#include <cstdlib>
#include "pixel.h"

using namespace std;
typedef unsigned char uchar;
class image {
	public:
		image();			//the image constructor (initializes everything)
		image(string filename);  //a image constructor that directly loads an image from disk
		image(image &other);//copy constructor
		~image();			//the image destructor  (deletes the dynamically created pixel array)
		pixel** getPixels();					//return the 2-dimensional pixels array
		int getWidth();						//return the width of the image
		int getHeight();					//return the height of the image
		void createNewImage(int width, int height); //this function deletes any current image data and creates a new image
													//with the specified width/height and allocates the needed number of pixels
													//dynamically. The new image contains four blocks with different color, red, blue, green, and black.
		
		//following two functions are provided.
		bool loadImage(string filename);		//load an image from the specified file path.  Return true if it works, false if it is not a valid image.
												//Note that we only accept images of the RGB 8bit colorspace!
		void saveImage(string filename);	   //Save an image to the specified path


			
	private:
		pixel** pixels;				// pixel data array for image 
		int width, height;		// stores the image dimensions 

		void pixelsToCImage(CImage* myImage);  //this function is called internally by the image class.
												//it converts our pixel struct array to a standard BGR uchar array with word spacing.
												//(Don't worry about what this does)
		
		

};

#endif 
Did you fix that 2D array and rerun?

Where does the program crash? If you don't know, run it in a debugger and take a look at the call stack.
access violation here imageBuf[j*scanline+i*3] = pixels[j][i].blue;

and i changed it to this
1
2
3
4
5
6
7
8
9
	//provide the code for this function
	pixel **p = new pixel*[width];

//	for (int i = 0; i < width; i++)
	//	p[i] = new pixel[width];

	for (int j = 0; j < height; j++)
		p[j] = new pixel[height];
here is the rest

pixel.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//A POD class (Plain Old Data Class) to hold one pixel's worth of data.  (Assuming the pixel is 24bpp and RGB)
//Note:  Not having getters and setters for the members of a class is only acceptable if you are using it as a Plain Old Data Class.
//If your class has any constructors, destructors, static members, virtual functions, derivations, or anything that is not a public
//data member...then you should follow the conventions we have practiced in class.  We are using a POD class in this case because it
//simplifies the usage of the pixel object as well as keeps it's memory footprint tiny (as we will have MANY of these classes loaded
//into memory at a given time.)

#ifndef PIXEL_H
#define PIXEL_H

class pixel
{
public:
	unsigned char red;		//the red component
	unsigned char green;	//the green component
	unsigned char blue;		//the blue component
};

#endif 


imageProcessing.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include "image.h"
#include "pixel.h"
#include <iostream>
#include <string>
using namespace std;


void RotateClockWise(image *imageIn); //this function rotate the imageIn 90 degreee clockwise
void RotateAntiClockWise(image *imageIn); //this function rotate the imageIn 90 degree anticlockwise

int main()
{
	//testing image 1
	image* currImage=new image("testing1.jpg");
	currImage->createNewImage(600,700); // create a new (4 blocks with different color) image with input size
	currImage->saveImage("fourColor.jpg");

	//testing image 2
	currImage=new image("testing2.jpg");
	RotateClockWise(currImage);
	currImage->saveImage("test2RotateClock.jpg");

	//testing image 3
	currImage=new image("testing3.jpg");
	RotateAntiClockWise(currImage);
	currImage->saveImage("test3RotateAntiClock.jpg");

	//testing copy concstructor using image 4
	image a("testing4.jpg");
	image b=a;
	b.createNewImage(100,100);
	b.saveImage("testing4color.jpg");
	// a should remain the same, so testing4.jpg will not be changed. 

	system("pause");
	return 0;
}

 void RotateClockWise(image *imageIn)
 {
	//please provide the code for this function
}

 void RotateAntiClockWise(image *imageIn)
 {
	 //please provide code for this function
 }
Last edited on
Should be:
1
2
3
4
5
	//provide the code for this function
	pixel **p = new pixel*[width];

	for (int j = 0; j < width; j++)
		p[j] = new pixel[height];
still an access reading violation on the same line
You should be using standard containers for that.

My guess is you probably corrupted the heap earlier.
Topic archived. No new replies allowed.