As a part of an assignment I am to construct a copy constructor for a bitmap loader/manipulator class. 2 of the things that must be copied are struct headers (containing a bunch of useless bitmap information, with a tiny bit of useful stuff).

Image Headerfile:

#pragma once
#include "Drawer.h"
#include <iostream>
using namespace std;

class CImager
{
	bool LoadFile (char * const);
	bool DoDMA (void);
	void DoFree();
	void DoError(int, char * const, ostream & const = cerr) const;
	BITMAPFILEHEADER * BMPFileHead;
	BITMAPINFOHEADER * BMPInfoHead;
	RGBTRIPLE *		   RGBVal;
	DWORD			   Pixels;
	int _iHeight,
		_iWidth;
public:
	void Blur();
	RGBTRIPLE BlurVal(int, int);
	void Write(char * const szFilename = "save.bmp");
	void EnhanceRed();
	void SwapRB();
	CImager(char * const);
	void Render() const;
	CImager(CImager &);
	~CImager(void);
};

The CCTor (so far)

CImager::CImager(CImager & objCopy)
{
	BMPInfoHead = 0;		
	BMPFileHead = 0;
	if (objCopy.BMPFileHead) //make sure that the object has some meat to copy
	{
		DoDMA(); //allocate memory for the headers
		BMPInfoHead = objCopy.BMPInfoHead;
		BMPFileHead = objCopy.BMPFileHead;
		RGBVal = new RGBTRIPLE [objCopy.Pixels]; 
		for (int i = 0; i < objCopy.Pixels; ++i)
			RGBVal[i] = objCopy.RGBVal[i];
	}
}

This fails miserably because BMPInfoHead points to the same location as objCopy.BMPInfoHead. Therefore it is not a true copy, just another pointer pointing to the original pointer's data. But there's about 20 members in each of these headers, and I think it would be rediculous to have to copy each one independently. I'm looking for a fast, preferably 1 line, method of copying entire structs. If you need more information/code, don't hesitate to ask. Thanks!

Recommended Answers

All 4 Replies

>DoDMA(); //allocate memory for the headers
>BMPInfoHead = objCopy.BMPInfoHead;
>BMPFileHead = objCopy.BMPFileHead;
This strikes me as a memory leak. If DoDMA allocates memory to BMPInfoHead and BMPFileHead, you lose your only reference to the new memory by overwriting the addresses with this in objCopy.

>I'm looking for a fast, preferably 1 line, method of copying entire structs.
Assuming your structs are well defined for deep copying:

DoDMA();
*BMPInfoHead = *objCopy.BMPInfoHead;
*BMPFileHead = *objCopy.BMPFileHead;

>DoDMA(); //allocate memory for the headers
>BMPInfoHead = objCopy.BMPInfoHead;
>BMPFileHead = objCopy.BMPFileHead;
This strikes me as a memory leak. If DoDMA allocates memory to BMPInfoHead and BMPFileHead, you lose your only reference to the new memory by overwriting the addresses with this in objCopy.

>I'm looking for a fast, preferably 1 line, method of copying entire structs.
Assuming your structs are well defined for deep copying:

DoDMA();
*BMPInfoHead = *objCopy.BMPInfoHead;
*BMPFileHead = *objCopy.BMPFileHead;

Yeah, it is a memory leak. And an assertion error. And not really a copy. Lol...I guess it's pretty much an all around failure. I'll try what you said, thanks!

You are looking for a deep copy silver bullet but your compiler does not know the semantics of this operation for your classes. YOU know the semantics. That's why user-defined copy constructor and overloaded assignment operator were invented in C++.

It's a matter of the right object model design. For every new class think about its possible copiable property in good time. Your compiler is not able to think in place of you.

Think about boost::shared_ptr using, for example...

It worked! Thanks a bunch. Here's the final code

CImager::CImager(CImager & objCopy): BMPInfoHead(0), BMPFileHead(0), _iHeight(objCopy._iHeight), _iWidth(objCopy._iWidth),  Pixels(objCopy.Pixels), _bError(objCopy._bError)//BMI the values
{								
	if (!_bError)
	{
		DoDMA();
		*BMPInfoHead = *objCopy.BMPInfoHead;
		*BMPFileHead = *objCopy.BMPFileHead;
		RGBVal = new RGBTRIPLE [objCopy.Pixels]; 
		for (unsigned int i = 0; i < objCopy.Pixels; i++)
		{
		RGBVal[i].rgbtRed = objCopy.RGBVal[i].rgbtRed;
		RGBVal[i].rgbtGreen = objCopy.RGBVal[i].rgbtGreen;
		RGBVal[i].rgbtBlue = objCopy.RGBVal[i].rgbtBlue;
		}
	}
	else
		DoError(8, "Cant copy corrupt Data");
}
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.