Thread: Function and pointer troubles

  1. #1
    Math wizard
    Join Date
    Dec 2006
    Location
    USA
    Posts
    582

    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.4 GHz i7-2600K CPU (OC'd to 4 GHz), 4 GB DDR3 RAM, X-Fi Platinum sound, GeForce 460, 1920x1440 resolution, 1250 GB HDD space, Visual C++ 2008 Express

  2. #2
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    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.

  3. #3
    Math wizard
    Join Date
    Dec 2006
    Location
    USA
    Posts
    582
    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.
    Last edited by ulillillia; 04-25-2009 at 12:01 AM. Reason: Different but similar case now used
    High elevation is the best elevation. The higher, the better the view!
    My computer: XP Pro SP3, 3.4 GHz i7-2600K CPU (OC'd to 4 GHz), 4 GB DDR3 RAM, X-Fi Platinum sound, GeForce 460, 1920x1440 resolution, 1250 GB HDD space, Visual C++ 2008 Express

  4. #4
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    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.

  5. #5
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    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.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  6. #6
    Math wizard
    Join Date
    Dec 2006
    Location
    USA
    Posts
    582
    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.4 GHz i7-2600K CPU (OC'd to 4 GHz), 4 GB DDR3 RAM, X-Fi Platinum sound, GeForce 460, 1920x1440 resolution, 1250 GB HDD space, Visual C++ 2008 Express

  7. #7
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    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);
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  8. #8
    Math wizard
    Join Date
    Dec 2006
    Location
    USA
    Posts
    582
    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.4 GHz i7-2600K CPU (OC'd to 4 GHz), 4 GB DDR3 RAM, X-Fi Platinum sound, GeForce 460, 1920x1440 resolution, 1250 GB HDD space, Visual C++ 2008 Express

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. sorting number
    By Leslie in forum C Programming
    Replies: 8
    Last Post: 05-20-2009, 04:23 AM
  2. Direct3D problem
    By cboard_member in forum Game Programming
    Replies: 10
    Last Post: 04-09-2006, 03:36 AM
  3. <Gulp>
    By kryptkat in forum Windows Programming
    Replies: 7
    Last Post: 01-14-2006, 01:03 PM
  4. Contest Results - May 27, 2002
    By ygfperson in forum A Brief History of Cprogramming.com
    Replies: 18
    Last Post: 06-18-2002, 01:27 PM
  5. Interface Question
    By smog890 in forum C Programming
    Replies: 11
    Last Post: 06-03-2002, 05:06 PM

Tags for this Thread