|
|
|||||||||
|
|||||||||
| |||||||||
|
|
|
| |||||||||
![]() |
|
|
«
Previous Thread
|
Next Thread
»
|
Thread Tools | Search this Thread | Rate Thread | Display Modes |
|
#1
|
|||
|
|||
|
2D dynamic array
Hello Everyone,
I am trying to read the data from a file and store into a 2D array(the file contains 540000 values), but i m facing memory issues. Then my friend suggested to create a dynamic 2D array, i thought thats simple but when i searched for the code on web, i was in vain and hardly implement those stuff. Can anyone please tell me how do i declare,intialize and access a 2D array dynamically. The code which i tried to implement is below, but i am ending up in errors Code:
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *fp; //file pointer for reading a file
double k;
char word[80];
double **DataLat=NULL;
DataLat=new double[360][1502]; // 2-D array for holding all the file values
int row=0, col=0; // row column and column declaration, used in 2-d array
fp = fopen("lat.txt", "r");
if ( fp == NULL )
{
puts("Unable to open the file");
exit(1); //terminate program
}
while(fscanf(fp,"%s",word)!=EOF)
{
k=atof(word);
DataLat[row][col]=k;
col++;
if(col==1502)
{
row++;
col=0;
}
if(row==359) exit(1);
}
delete []DataLat;
fclose( fp );
}
thanks, Kedar |
|
#2
|
||||
|
||||
|
Code:
#include <iostream>
#include <fstream>
int main()
{
const int ROWS = 360, COLS = 1502;
// Allocate 2D array.
double **data = new double*[ROWS];
for ( std::size_t r = 0; r < 360; ++r )
{
data[r] = new double[COLS];
}
// Read data into array.
std::ifstream file("file.txt");
if ( file )
{
for ( int r = 0; r < ROWS; ++r )
{
for ( int c = 0; c < COLS; ++c )
{
file >> data[r][c];
}
}
file.close();
}
// Do stuff...
// De-allocate 2D array.
for ( std::size_t r = 0; r < 360; ++r )
{
delete[] data[r];
}
delete[] data;
return 0;
}
__________________
Any advertisement triggered by IntelliTxt in this post is not endorsed by the author of this post. |
|
#3
|
|||
|
|||
|
Thanks Dave,
That was a quick reply, I am trying to retreive the values that are stored in the array, but i guess, i m doing something wrong. Here is what i did, let me know if if do something wrong. Code:
#include <iostream>
#include <fstream>
int main()
{
const int ROWS = 360, COLS = 1502;
// Allocate 2D array.
double **data = new double*[ROWS];
for ( std::size_t r = 0; r < 360; ++r )
{
data[r] = new double[COLS];
}
// Read data into array.
std::ifstream file("lon.txt");
if ( file )
{
for ( int r = 0; r < ROWS; ++r )
{
for ( int c = 0; c < COLS; ++c )
{
file >> data[r][c];
}
}
file.close();
}
for ( int r = 0; r < ROWS; ++r )
{
for ( int c = 0; c < COLS; ++c )
{
printf("%f\n", data[r][c]);
}
}
// Do stuff...
// De-allocate 2D array.
for ( std::size_t r = 0; r < 360; ++r )
{
delete[] data[r];
}
delete[] data;
return 0;
}
|
|
#4
|
||||
|
||||
|
I don't see it straight away, but shortly after I posted I thought about editing my post to add in better error checking. (I also now notice a couple places I forgot to change 360 to ROWS.)
How about something like this? Code:
#include <iostream>
#include <fstream>
double **my_alloc(int rows, int cols); // Allocate 2D array.
void my_cleanup(double **data, int rows); // De-allocate 2D array.
int my_read(double **data, int rows, int cols)
{
int count = 0;
std::ifstream file("lon.txt");
if ( file )
{
for ( int r = 0; r < rows; ++r )
{
for ( int c = 0; c < cols; ++c )
{
if ( !(file >> data[r][c]) )
{
return count;
}
++count;
}
}
}
return count;
}
void do_stuff(double **data, int rows, int cols, int count)
{
for ( int r = 0; r < rows; ++r )
{
for ( int c = 0; c < cols; ++c )
{
std::cout << "data[" << r << "][" << c << "] = " << data[r][c] << '\n';
if ( --count == 0 )
{
return;
}
}
}
}
int main()
{
const int ROWS = 360, COLS = 1502;
double **data = my_alloc(ROWS, COLS);
int count = my_read(data, ROWS, COLS);
do_stuff(data, ROWS, COLS, count);
my_cleanup(data, ROWS);
return 0;
}
double **my_alloc(int rows, int cols)
{
double **data = new double*[rows];
for ( std::size_t r = 0; r < rows; ++r )
{
data[r] = new double[cols];
}
return data;
}
void my_cleanup(double **data, int rows)
{
for ( std::size_t r = 0; r < rows; ++r )
{
delete[] data[r];
}
delete[] data;
}
|
|
#5
|
|||
|
|||
|
Eye-catching post!
I am presently trying to improve my own programs, which use much dynamic memory, so this thread is timely. In reading through the rest of this thread, several questions came to mind: 1) The OP indicated he was having memory problems. So how does using dynamic memory solve that problem? If you explictly define the array to be a fixed size [360][1502] or dynamically allocate it to be 360X1502, you're still allocating the same size of memory aren't you? Am I making a wrong assumption? 2) Dave, what about error checking if the memory allocation fails? Shouldn't there be a check to see if "new" fails? What is the best way of checking and dealing with this possibility? 3) Dave, I notice you did not use <vector>. I haven't used it myself, but was planning to go that way. In my recent surfing/research, it seems quite well-regarded. Is there a reason you did not use it? If it is, indeed, a good way to go, could you please post an example using <vector>. (My programs include several dynamic 2D arrays, as well as several dynamic 1D arrays. Doing all this memory management gets quite onerous; I am hoping that using <vector> would provide me a more concise option). Regards, David |
|
#6
|
||||||
|
||||||
|
Quote:
Quote:
http://www.parashift.com/c++-faq-li...t.html#faq-16.6 Quote:
Quote:
[edit]One possible version. Code:
#include <iostream>
#include <fstream>
#include <vector>
int main()
{
std::ifstream file("lon.txt");
if ( file )
{
const int ROWS = 360, COLS = 1502;
std::vector< std::vector< double > > data;
for ( std::size_t r = 0; r < ROWS; ++r )
{
std::vector< double > col;
for ( std::size_t c = 0; c < COLS; ++c )
{
double value;
if ( file >> value )
{
col.push_back(value);
}
}
data.push_back(col);
}
for ( std::size_t r = 0, rows = data.size(); r < rows; ++r )
{
for ( std::size_t c = 0, cols = data[r].size(); c < cols; ++c )
{
std::cout << "data[" << r << "][" << c << "] = " << data[r][c] << '\n';
}
}
}
return 0;
}
Last edited by Dave Sinkula : March 2nd, 2006 at 12:00 PM. |
|
#7
|
||||
|
||||
|
>> what about error checking if the memory allocation fails? Shouldn't there be a check to see if "new" fails? What is the best way of checking and dealing with this possibility?
There are two ways to handle this. The C++ standard actually specifies two forms of the new keyword. By default, if new cannot allocate the memory, it throws the bad_alloc exception. If you don't have an exception handler, the default handler will stop the program (which is what 99% of C programs that check for malloc() failure also do!) Before the official standard though, some C++ compilers used to return NULL if the new failed. This allowed you to say: Code:
int *p = new int[20];
if (!p) {
cerr << "Failed alloc";
exit(0);
}
very much like C's malloc() function. In order to preserve this behavior for backward compatibility, the C++ standard overloads the new operator for nothrow. To use this, you need to #include new Code:
#include <new> // Need this for std::nothrow
int *p = new(std::nothrow) int[20];
if (!p) {
// do something here
}
This form will not throw an exception if the allocation fails. Error handling is similar to C in this case.
__________________
Up the Irons What Would Jimi Do? Smash amps. Burn guitar. Take the groupies home. "Death Before Dishonour, my Friends!!" - Bruce D ickinson, Iron Maiden Aug 20, 2005 @ OzzFest Down with Sharon Osbourne Puzzle of the Month solved by Keath and KevinADC, superior perl programmers of the month |
|
#8
|
|||
|
|||
|
Thanks a lot Dave, that was awesome.
|
|
#9
|
|||
|
|||
|
Hello again, Dave and Scorpions4ever.
Thanks for your comments. I actually do use the check for NULL approach. You are correct: it IS a very onerous process. I have been using Microsoft’s Visual C++ Version 6 for a number of years, somebody told me that approach would work (it does), so I have just been using the same approach for the several numerical mathematics programs I have written. I am now planning to clean up my source code and post it online, so in the near future, I intend to master some better techniques (one reason for joining this forum). In fact, over the past few days, I have been working on a webpage on which I have posted a C++ program that calculates the eigenvalues of a matrix. The Intro is here: Intro and the source code itself is here: Source Code Page I am calling this version 0. Version 1 will probably use the try-catch approach (I assume it is a more standards-compliant approach). Based on what I have read so far, I should be able to just wrap lines 101 through 136 in try braces, and write a catch routine further down. (Is this assumption correct?) Version 2 will show the most basic use of the <vector> class. I have read about some very fancy things that can be done with class definitions, but I think they start to hide the algorithm. I actually want to show the algorithm, so I don’t plan to do anything too sophisticated. Constructive comments regarding my memory management, or any other comments that you can offer that would make my code better, are always welcome. Regards, David |
![]() |
| Viewing: Dev Shed Forums > Programming Languages > C Programming > 2D dynamic array |
| Thread Tools | Search this Thread |
| Display Modes | Rate This Thread |
|
|
|
|
|