C Board  

Go Back   C Board > General Programming Boards > C Programming

Reply
 
LinkBack Thread Tools Display Modes
Old 04-24-2009, 10:04 PM   #1
Math wizard
 
Join Date: Dec 2006
Location: Minot, ND, USA
Posts: 516
Function and pointer troubles

For malloc to work, I need to know how much memory is needed. For convenience, since it's done a lot, I've put this into a function as a parameter. The function is to set the global variable for the memory usage then malloc the amount of memory needed. Trouble is, I'm always getting 0. Using the debugger, I'm seeing that it is reaching the line, but it's not being set, and thus malloc is allocating 0 bytes, causing problems.

The main essentials are these:

Code:
unsigned char *SkyBlueData; // data to malloc
unsigned int SkyBlueMemoryUsage; // memory used
LPVOID SkyBlueDataPointer;
BITMAPINFO SkyBlueMainInfo;
BITMAPINFOHEADER SkyBlueInfo;
LPBITMAPINFOHEADER SkyBlueInfoPointer;
HBITMAP SkyBlueBMPHandle;
The function declaration is this:

Code:
int LoadImageFile(const char FileName[64], int FileType, int LoadType, BITMAPINFOHEADER *BMPInfo, unsigned char *BMPData, int FogUsed, double ObjectScaling, unsigned int *BMPMemoryUsage, unsigned int Special)
This is the key area:

Code:
	BMPMemoryUsage = BMPInfo->biSizeImage; // sets the memory usage
	BMPData = malloc(BMPMemoryUsage);
	fread(BMPData, 1, BMPMemoryUsage, FileHandle);
This is how the function is called, with other essentials:

Code:
	SkyBlueInfoPointer = &SkyBlueInfo;
	LoadImageFile("scenery\\SkyBlue.bmp", 1, 0, &SkyBlueInfo, &SkyBlueData, 0, 0.0, &SkyBlueMemoryUsage, 0);
	SkyBlueDataPointer = &SkyBlueData;
I can't just set the specific variable in the function - it'll be the only one set. Basically, I want to pass the SkyBlueMemoryUsage variable to the function so it can get set int the function for malloc to work properly and to keep a log of the memory usage. In other words, I have a global variable, A, that want a function, B, to set within it with the variable to be changed, A, referenced in the function's parameters.
__________________
High elevation is the best elevation. The higher, the better the view!
My computer: XP Pro SP3, 3.17 GHz C2D CPU, 4 GB DDRII800 RAM (3 GB effective), X-Fi Platinum sound, GeForce 7600 GT, 1920x1440 resolution, 250 GB HDD, Visual C++ 2008 Express
ulillillia is offline   Reply With Quote
Old 04-24-2009, 11:08 PM   #2
Registered User
 
Join Date: Jun 2005
Posts: 1,343
Before calling LoadImageFile, SkyBlueInfo.biSizeImage needs to be set to an appropriate value.

You also need to ensure that you dereference pointers in order to change the value they point to. In other words, fix the compilation errors you're getting that you're neglecting to tell us about.
grumpy is offline   Reply With Quote
Old 04-24-2009, 11:21 PM   #3
Math wizard
 
Join Date: Dec 2006
Location: Minot, ND, USA
Posts: 516
I'm not getting any compiler errors or any warnings relevant to this function call (how else could I have used the debugger to see that I'm getting zero?). I've got the info structure filled out, including biSizeImage (and the many others), done by reading from the BMP image. How do you dereference a pointer? I'm confused. The other areas, the BMPInfo and BMPData elements work fine as is, but not this single variable that doesn't use an array or is part of a struct.

Edit: By using biSizeImage instead, malloc is working... somewhat. I have new problem now. Before using malloc, BMPData filled in the global variable correctly and I could see the image just fine. With using malloc, nothing shows up, as if it's allocating a bunch of local pointers because what is referenced to by the parameter is zero - a pointer that points to nothing.

Here's the updated function declaration:

Code:
int LoadImageFile(const char FileName[64], int FileType, int LoadType, BITMAPINFOHEADER *BMPInfo, unsigned char *BMPData, int FogUsed, double ObjectScaling, unsigned int Special)
This is the area for malloc (it's supposedly allocating an array of pointers instead of actual data but I don't know how to get it to reference the data I passed onto the function instead of this parameter):

Code:
BMPData = malloc(BMPInfo->biSizeImage);
			fread(BMPData, 1, BMPInfo->biSizeImage, FileHandle); // read the main image data // reads in BGR format
Here's the updated call to the function:

Code:
LoadImageFile("scenery\\SkyBlue.bmp", 1, 0, &SkyBlueInfo, SkyBlueData, 0, 0.0, 0); // current version
// LoadImageFile("scenery\\SkyBlue.bmp", 1, 0, &SkyBlueInfo, &SkyBlueData, 0, 0.0, 0); // tried this, but doesn't work
It's probably the dereferencing of pointers (whatever that means) that's getting at me. Why it works for BMPInfo, that I don't know. I also don't know why it works for BMPData without malloc, but doesn't with it.
__________________
High elevation is the best elevation. The higher, the better the view!
My computer: XP Pro SP3, 3.17 GHz C2D CPU, 4 GB DDRII800 RAM (3 GB effective), X-Fi Platinum sound, GeForce 7600 GT, 1920x1440 resolution, 250 GB HDD, Visual C++ 2008 Express

Last edited by ulillillia; 04-25-2009 at 12:01 AM. Reason: Different but similar case now used
ulillillia is offline   Reply With Quote
Old 04-25-2009, 12:36 AM   #4
Registered User
 
Join Date: Jun 2005
Posts: 1,343
Now you're showing different code.

In your first post, your function declared BMPMemoryUsage as a pointer to unsigned int, and then you had a line "BMPMemoryUsage = BMPInfo->biSizeImage;". The left hand side of that expression is a pointer, and the right is (presumably) an integral value. The types don't match, so that would have resulted in a compilation error.

Dereferencing a pointer is any act of accessing or modifying whatever that pointer points at. For example, "*BMPMemoryUsage = 42;" dereferences the pointer BMPMemoryUsage, and sets the value pointed at to 42. Another example is that "malloc(BMPInfo->biSizeImage)" dereferences BMPInfo in order to obtain the biSizeImage member.

You clearly don't understand what your problem is, and you're describing your guess as to where the problem is. That is forcing anyone here to play "blind mans bluff" .... you describe something that may, or may not, be relevant to your problem and others have to guess what the problem really is.

Try providing a small but complete example of actual code which exhibits your concern, explain what you expect to code to do and how that's different from what it does.
grumpy is offline   Reply With Quote
Old 04-25-2009, 02:42 PM   #5
Senior software engineer
 
brewbuck's Avatar
 
Join Date: Mar 2007
Location: Portland, OR
Posts: 5,381
It is allowed for biSizeImage to be zero (and obviously it is, since you are passing 0 to malloc -- there is no magic here). You must calculate it yourself from other information in the header.
__________________
"Congratulations on your purchase. To begin using your quantum computer, set the power switch to both off and on simultaneously." -- raftpeople@slashdot
brewbuck is online now   Reply With Quote
Old 04-25-2009, 03:46 PM   #6
Math wizard
 
Join Date: Dec 2006
Location: Minot, ND, USA
Posts: 516
biSizeImage is not 0, I checked it. Punching numbers into calculator, I see that it exactly matches what the calculation shows. If you want the full code, here:

Code:
int LoadImageFile(const char FileName[64], int FileType, int LoadType, BITMAPINFOHEADER *BMPInfo, unsigned char *BMPData, int FogUsed, double ObjectScaling, unsigned int Special)
{
	char BasePath[192]; // the base path, that of which started from
	char FullFileName[256]; // the full path combining the base path and the parameter
	unsigned int ArrayIndex = 0;
	float NewColor = 0;
	const float FogIntensity = (float)ObjectScaling;
	const float FogRange = (float)visibility;
	const float FogColorRed = (float)(FogColor[2]);
	const float FogColorGreen = (float)(FogColor[1]);
	const float FogColorBlue = (float)(FogColor[0]);
	unsigned int CurrentRow;
	unsigned int CurrentPixel;
	float BaseScaling;
	
	GetCurrentDirectory(MAX_PATH, BasePath);
	sprintf(FullFileName, "%s\\images\\%s", BasePath, FileName); // combine the base path and file name
	FileHandle = fopen(FullFileName, "rb"); // read the source file to display, binary mode
	
	if (FileHandle == 0) // if the file can't be found
	{
		sprintf(WarningString, "Error:  This file cannot be found:\n%s", FullFileName); // an error since the file can't be found
		MessageBox(WindowHandle, WarningString, "File not found", MB_OK | MB_ICONHAND);
		return 1; // indicates an error occurred
	}
	
	if (FileType == 1) // reading a BMP file
	{
		if (LoadType == 0) // normal full load
		{
			fseek(FileHandle, 14, SEEK_SET); // skip the basic file header data but read from the info header
			fread(&BMPInfo->biSize, 4, 1, FileHandle); // bytes 0E through 11
			fread(&BMPInfo->biWidth, 4, 1, FileHandle); // bytes 12 through 15
			fread(&BMPInfo->biHeight, 4, 1, FileHandle); // bytes 16 through 19
			fread(&BMPInfo->biPlanes, 2, 1, FileHandle); // bytes 1A and 1B
			fread(&BMPInfo->biBitCount, 2, 1, FileHandle); // bytes 1C and 1D
			fread(&BMPInfo->biCompression, 4, 1, FileHandle); // bytes 1E through 21
			fread(&BMPInfo->biSizeImage, 4, 1, FileHandle); // bytes 22 through 25
			fread(&BMPInfo->biXPelsPerMeter, 4, 1, FileHandle); // bytes 26 through 29
			fread(&BMPInfo->biYPelsPerMeter, 4, 1, FileHandle); // bytes 2A through 2D
			fread(&BMPInfo->biClrUsed, 4, 1, FileHandle); // bytes 2E through 31
			fread(&BMPInfo->biClrImportant, 4, 1, FileHandle); // bytes 32 through 35
			
			*BMPData = malloc(BMPInfo->biSizeImage);
			fread(BMPData, 1, BMPInfo->biSizeImage, FileHandle); // read the main image data // reads in BGR format
		}
		
		if (LoadType == 1) // just a reload
		{
			fseek(FileHandle, 54, SEEK_SET); // skip to the main image data
			fread(BMPData, 1, BMPInfo->biSizeImage, FileHandle); // read the main image data // reads in BGR format
		}
	}
... // similar case for TGA images, then fog processing and premultiplication
}

... // in WinMain:
	SkyBlueInfoPointer = &SkyBlueInfo;
	LoadImageFile("scenery\\SkyBlue.bmp", 1, 0, &SkyBlueInfo, &SkyBlueData, 0, 0.0, 0);
	SkyBlueDataPointer = &SkyBlueData; // copies the pointer
If I keep the & in the function call for this part, I can't see the warnings list - it's empty. Removing it and I do. With it removed, I get this as the only warning, involving that line with malloc. As is, I get the top warning. By having only the top one have the ampersand, I get the two warnings at the bottom:

Code:
1>.\Platform Masters.c(383) : warning C4047: '=' : 'unsigned char' differs in levels of indirection from 'void *'

1>.\Platform Masters.c(2784) : warning C4047: 'function' : 'unsigned char *' differs in levels of indirection from 'unsigned char **'
1>.\Platform Masters.c(2784) : warning C4024: 'LoadImageFile' : different types for formal and actual parameter 5
The only other warnings are from mmsystem (a Windows element) and unreferenced local variables and parameters.

When I run it, I get an unhandled exception error. With the ampersand, it happens with "free". Without the ampersand, it happens at malloc.

In addition, I didn't know you could have the * in front of something when an = is to follow. If you want to look at the bitmap image so you can see that biSizeImage is not zero, I can zip it up and give a link to it.
__________________
High elevation is the best elevation. The higher, the better the view!
My computer: XP Pro SP3, 3.17 GHz C2D CPU, 4 GB DDRII800 RAM (3 GB effective), X-Fi Platinum sound, GeForce 7600 GT, 1920x1440 resolution, 250 GB HDD, Visual C++ 2008 Express
ulillillia is offline   Reply With Quote
Old 04-25-2009, 04:12 PM   #7
Senior software engineer
 
brewbuck's Avatar
 
Join Date: Mar 2007
Location: Portland, OR
Posts: 5,381
Quote:
Code:
*BMPData = malloc(BMPInfo->biSizeImage);
You are assigning the result of malloc() to wherever BMPData is pointing, i.e. nowhere. You should have:

Code:
BMPData = malloc(BMPInfo->biSizeImage);
__________________
"Congratulations on your purchase. To begin using your quantum computer, set the power switch to both off and on simultaneously." -- raftpeople@slashdot
brewbuck is online now   Reply With Quote
Old 04-25-2009, 04:25 PM   #8
Math wizard
 
Join Date: Dec 2006
Location: Minot, ND, USA
Posts: 516
I've made this change, and still nothing happens and it's still the same case - a bad pointer. I have 2 calls to the function. One uses the & for the data, the other doesn't. I put a breakpoint on this line:

Code:
SkyBlueDataPointer = &SkyBlueData;
I see that SkyBlueDataPointer is nonzero and SkyBlueData (which contains the image data) is zero when I put the mouse over them. Remove the ampersand and both are zero. If it helps, these are the two function calls:

Code:
	SkyBlueInfoPointer = &SkyBlueInfo;
	LoadImageFile("scenery\\SkyBlue.bmp", 1, 0, &SkyBlueInfo, &SkyBlueData, 0, 0.0, 0);
	SkyBlueDataPointer = &SkyBlueData;
	FullFogDayInfoPointer = &FullFogDayInfo;
	LoadImageFile("scenery\\FullFogDay.bmp", 1, 0, &FullFogDayInfo, FullFogDayData, 0, 0.0, 0);
	FullFogDayDataPointer = &FullFogDayData;
The top one, line 2784 is the one with the warnings, but the bottom one doesn't have it. Both of which have bad pointers. It's for this reason that I thought malloc was allocating to BMPData instead of the real data.
__________________
High elevation is the best elevation. The higher, the better the view!
My computer: XP Pro SP3, 3.17 GHz C2D CPU, 4 GB DDRII800 RAM (3 GB effective), X-Fi Platinum sound, GeForce 7600 GT, 1920x1440 resolution, 250 GB HDD, Visual C++ 2008 Express
ulillillia is offline   Reply With Quote
Reply

Tags
function, malloc, pointer, set variable

Thread Tools
Display Modes

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
sorting number Leslie C Programming 8 05-20-2009 04:23 AM
Direct3D problem ahluka Game Programming 10 04-09-2006 03:36 AM
<Gulp> kryptkat Windows Programming 7 01-14-2006 01:03 PM
Contest Results - May 27, 2002 ygfperson A Brief History of Cprogramming.com 18 06-18-2002 01:27 PM
Interface Question smog890 C Programming 11 06-03-2002 05:06 PM


All times are GMT -6. The time now is 09:27 PM.


Powered by vBulletin® Version 3.8.1
Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.3.0 RC2

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22