GIDForums  

Go Back   GIDForums > Computer Programming Forums > C++ Forum
User Name
Password
Register FAQ Members List Calendar Search Today's Posts Mark Forums Read

 
 
Thread Tools Search this Thread Rate Thread
  #1  
Old 13-May-2009, 04:24
bbjapang bbjapang is offline
New Member
 
Join Date: Jul 2008
Posts: 4
bbjapang is on a distinguished road

Reading a binary file into a dynamically allocated 2D array


Hi all,
I have a problem with this (see title). So, I have a binary file which contains a matrix. The first 4 bytes of the file are the dimensions of the matrix. The following bytes are the elements of it. Here is the code:

CPP / C++ / C Code:
int readImg(char *filename)
{
	int i, j;
	ifstream imgData(filename, ios::binary);

	// Read the image size
	imgData.read(reinterpret_cast<char*>(&imgW),sizeof(short));
        imgData.read(reinterpret_cast<char*>(&imgH),sizeof(short));

	imgR = new UCHAR *[imgW];
	imgG = new UCHAR *[imgW];
	imgB = new UCHAR *[imgW];
	for (i=0; i<imgW; i++)
	{
		*(imgR+i) = new UCHAR [imgH];
		*(imgG+i) = new UCHAR [imgH];
		*(imgB+i) = new UCHAR [imgH];
	}

	imgData.read(reinterpret_cast<char*>(imgR),imgW*imgH*sizeof(UCHAR));
	imgData.read(reinterpret_cast<char*>(imgG),imgW*imgH*sizeof(UCHAR));
	imgData.read(reinterpret_cast<char*>(imgB),imgW*imgH*sizeof(UCHAR));

	return 0;
}

The method works with fixed-size 2D array, so I tried this with a dynamically allocated array. However, the program crashes at runtime.

Anybody knows how to perform this..?

Many thanks before!

Cheers,
Arthur
Last edited by LuciWiz : 13-May-2009 at 06:22. Reason: Please insert your C++ code between [cpp] & [/cpp] tags
  #2  
Old 13-May-2009, 12:08
Howard_L Howard_L is offline
Regular Member
 
Join Date: Apr 2007
Location: Maryland/PA, USA
Posts: 802
Howard_L is a jewel in the roughHoward_L is a jewel in the roughHoward_L is a jewel in the rough

Re: Reading a binary file into a dynamically allocated 2D array


Not suprisinlgly this is a common question. (I need to review it too!)
Searching the site can be VERY helpful.
Here is one example of allocating and working with a 2d array: gidforums.com/t-18393.html
It should help you see what you need to change in your function.
You might also want to include a sample main() for us to try out your function with like:
CPP / C++ / C Code:
#include <iostream>
#include <fstream>
using namespace std;

/* I'm guessing you have these globals */
short imgW, imgH, imgR, imgG, imgB;  /* <--these global: not such a good idea */
typedef unsigned char UCHAR;

int readImg(char *filename);

int main(void)
{
  char  charray[3][4] = { {1,2,3,4}, {5,6,7,8}, {9,10,11,12} };
  short y, x;
  char  fname[] = "090513_file_to_dynamic_array-1.dat";

  x= (sizeof(charray[0]) / sizeof(char));
  y= (sizeof(charray) / x);
  cout << "y= " << y << "  x== " << x << endl;

  ofstream fout(fname, ios::binary);
  fout.write( reinterpret_cast<char*>(&x), sizeof(short) ) ;
  fout.write( reinterpret_cast<char*>(&y), sizeof(short) ) ;
  fout.write( charray[0], (y * x) );
  fout.close();

  readImg( fname);

  return 0;
}
/*  
that file looks like this:
forums>  hexdump -C   090513_file_to_dynamic_array-1.dat
00000000  04 00 03 00 01 02 03 04  05 06 07 08 09 0a 0b 0c  |................|
00000010
*/
That will make it easier for other people to try it out themselves.
  #3  
Old 13-May-2009, 14:05
davekw7x davekw7x is offline
Outstanding Member
 
Join Date: Feb 2004
Location: Left Coast, USA
Posts: 5,218
davekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to behold

Re: Reading a binary file into a dynamically allocated 2D array


Quote:
Originally Posted by bbjapang
...problem...

1. Give us the file specification. Exactly.

2. Give us the exact specification of the function that is going to read the data. (What are the function parameters: inputs, outputs?)

3. Show us the code of the function that works with a 2-D array.

4. If you can't show us the entire program, then at least show us the declarations in the calling function (main() or whatever) and show us how it calls the function that reads the data from the file.

5. Show us how you are going to use whatever data structure that holds the data that you read from the file. (Do you expect to have three 2-D arrays and access each one by "row" and "column" or what?)


Regards,

Dave
  #4  
Old 13-May-2009, 20:16
bbjapang bbjapang is offline
New Member
 
Join Date: Jul 2008
Posts: 4
bbjapang is on a distinguished road

Re: Reading a binary file into a dynamically allocated 2D array


Here is the complete code:

CPP / C++ / C Code:
#include <iostream>
#include <iomanip>
#include <fstream>
#include <ctime>
#include <sstream>

using namespace std;

short		imgH, imgW;
UCHAR		**imgR;				
UCHAR		**imgG;
UCHAR		**imgB;

int readImg(char*);

int main(int argc, char *argv[])
{
	int i,j;

	// Read the model image
	readImg(argv[1]);

	for (i=0; i<10; i++)
	{
		for (j=150; j<160; j++)
			cout << (int) imgR[j][i] << ' ';
		cout << endl;
	}

	for (i=0; i<imgW; i++)
	{
		delete[] *(imgR+i);
		delete[] *(imgG+i);
		delete[] *(imgB+i);
	}
	delete[] imgR;
	delete[] imgG;
	delete[] imgB;

	return 0;
}

int readImg(char *filename)
{
	int	i, j;
	UCHAR data; 
	ifstream imgData(filename, ios::binary);

	// Read the image size
	imgData.read(reinterpret_cast<char*>(&imgW),sizeof(short));
	imgData.read(reinterpret_cast<char*>(&imgH),sizeof(short));

	imgR = new UCHAR *[imgW];
	imgG = new UCHAR *[imgW];
	imgB = new UCHAR *[imgW];
	for (i=0; i<imgW; i++)
	{
		*(imgR+i) = new UCHAR [imgH];
		*(imgG+i) = new UCHAR [imgH];
		*(imgB+i) = new UCHAR [imgH];
	}

	// Read the image data - still need to find out how to read it conveniently
	imgData.read(reinterpret_cast<char*>(imgR),imgW*imgH*sizeof(UCHAR));
	imgData.read(reinterpret_cast<char*>(imgG),imgW*imgH*sizeof(UCHAR));
	imgData.read(reinterpret_cast<char*>(imgB),imgW*imgH*sizeof(UCHAR));

	return 0;
}

The purpose is to read an image from a binary file, which is created for this purpose only. The first 4 bytes (2 shorts) contain the dimension of the image, then the following bytes are the image data.
The program crashes at runtime. However, regarding the ifstream::read function, if I use 2D-array with fixed size, e.g.

CPP / C++ / C Code:
UCHAR  imgR[512][512];
...
...
	imgData.read(reinterpret_cast<char*>(imgR),512*512*sizeof(UCHAR));
...

the program works perfectly.

Cheers,
Arthur
Last edited by admin : 14-May-2009 at 20:04. Reason: Please insert your example C/C++ codes between [CPP] and [/CPP] tags
  #5  
Old 13-May-2009, 23:31
davekw7x davekw7x is offline
Outstanding Member
 
Join Date: Feb 2004
Location: Left Coast, USA
Posts: 5,218
davekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to behold

Re: Reading a binary file into a dynamically allocated 2D array


Quote:
Originally Posted by bbjapang
Here is the complete code...


The following statement tries to store 262,144 chars from the file into a contiguous area in memory, starting at the address pointed to by imgR

CPP / C++ / C Code:
	imgData.read(reinterpret_cast<char*>(imgR),512*512*sizeof(UCHAR));

However, assuming that the values of imgW and imgH are 512, I see that your program has 512 different allocation statements for 512 different chunks of memory imgR. So the memory blocks that hold the rows or rgbR data are not contiguous. See Footnote.

Successive blocks of allocated memory are not guaranteed to be contiguous, and, in fact, I can just about guarantee that blocks of memory separately allocated by new (or malloc(), or whatever...) are not contiguous. However, your 512 blocks for the 512 rows of imgR data aren't even allocated successively. The blocks for each row of rgbG and rgbB follow the blocks for the rgbR rows.

Here's the deal: If you allocate memory a row at a time, you can't read multiple rows at a time. Period. Full stop.

In particular:
If you allocate contiguous storage a 512 bytes at a time, you can't read more than 512 bytes with a single read() statement.

If you want to read a block of 262,144 bytes into contiguous storage with a single read() statement, you have to allocate 262,144 bytes at a time. I'm guessing that this is not what you need to do, since accessing the data as a 2-D array by row and column index is another matter, and won't work the way that you seem to want it to.

Regards,

Dave

Footnote:

The statement unsigned char imgR[2][512]; allocates 1024 bytes of contiguous memory in row-major order. That is, it is absolutely guaranteed that imgR[1][0] is stored immediately after imgR[0][511]

Assuming that imgR is a pointer-to-pointer to unsigned char, and that memory for two or more pointers has been allocated and the starting point assigned to imgR, the following two statements allocate two separate blocks of 512 bytes each.
CPP / C++ / C Code:
imgR[0] = new unsigned char[512];
imgR[1] = new unsigned char[512];

I hate to repeat myself, but: Each block consists of 512 chars of contiguous storage. The two blocks are not guaranteed to be contiguous. That is, it is not guaranteed that imgR[1][0] immediately follows imgR[0][511] (And in all compilers that you are likely to run across on your workstation these days they are definitely not contiguous.)
Last edited by davekw7x : 14-May-2009 at 00:07.
 
 

Recent GIDBlogAccepted for Ph.D. program by crystalattice

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Power Calibration Error In Nero Fix (hopefully) matt3678 Computer Hardware Forum 60 20-Aug-2009 06:04
contents of .txt file into 2D array anirudhroxrulz C Programming Language 4 10-Apr-2008 23:45
Airport Log program using 3D linked List : problem reading from file batrsau C Programming Language 11 29-Feb-2008 08:44
Double linked List & File System NatsoumiMaya C Programming Language 1 10-Feb-2008 09:23
After execution - Error cannot locate /Skin File? WSCH C++ Forum 1 05-Mar-2005 21:03

Network Sites: GIDNetwork · GIDWebHosts · GIDSearch · Learning Journal by J de Silva, The

All times are GMT -6. The time now is 15:40.


vBulletin, Copyright © 2000 - 2009, Jelsoft Enterprises Ltd.