By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
454,937 Members | 1,148 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 454,937 IT Pros & Developers. It's quick & easy.

How do you define 2D arrays using New Operator?

P: n/a
I would like to dynamically allocate in a sub a 2 dimensional Array

float *myarray = new float [n][n];

of course I get an error. How do you allocate a 2D array using the New
operator?

I currently use

static float gxy[10000][10000];

but I don't want my array in the sub to use up my stack space.

Also does the New operator automatically make the values in the array static if
the array pointer is never deleted when the sub is ended? That is I only
allocate the array once the first time I enter the sub. All subsequent sub
calls skip the array allocation section and use the array pointer that was
allocated in the first sub call. The pointer and values in the array are not
touched when the sub ends?

Thanks for any help.

Dennis

Jul 22 '05 #1
Share this Question
Share on Google+
34 Replies


P: n/a

<De****@NoSpam.com> wrote in message
news:47********************************@4ax.com...
I would like to dynamically allocate in a sub a 2 dimensional Array

float *myarray = new float [n][n];

of course I get an error. How do you allocate a 2D array using the New
operator?
http://www.parashift.com/c++-faq-lit...html#faq-16.15
I currently use

static float gxy[10000][10000];

but I don't want my array in the sub to use up my stack space.

Also does the New operator automatically make the values in the array static if the array pointer is never deleted when the sub is ended?
No. An object can have one of three 'storage durations':
automatic, static, or allocated. 'new' allocates an object,
and the object 'lives' until specifically deallocated with
'delete', or the program terminates.
That is I only
allocate the array once the first time I enter the sub. All subsequent sub calls skip the array allocation section and use the array pointer that was
allocated in the first sub call. The pointer and values in the array are not touched when the sub ends?


See above.

-Mike
Jul 22 '05 #2

P: n/a
In article <47********************************@4ax.com>,
De****@NoSpam.com wrote:
I would like to dynamically allocate in a sub a 2 dimensional Array

float *myarray = new float [n][n];

of course I get an error. How do you allocate a 2D array using the New
operator?


Use a class:
========== ========== ========== ========== ========== ==========

template < typename T, typename U = std::deque< T > >
class Matrix {
public:
typedef typename U::size_type size_type;
typedef typename U::reference reference;
typedef typename U::const_reference const_reference;
typedef typename U::iterator iterator;
typedef typename U::const_iterator const_iterator;

Matrix(): h_limit( 0 ), v_limit( 0 ) { }
Matrix( size_type h, size_type v ): buffer( h * v ), h_limit( h ),
v_limit( v ) { }

reference operator()( size_type h, size_type v ) {
check_limits( h, v );
return buffer[h_limit * h + v];
}

const_reference operator()( size_type h, size_type v ) const {
check_limits( h, v );
return buffer[h_limit * h + v];
}

iterator begin() { return buffer.begin(); }
iterator end() { return buffer.end(); }
const_iterator begin() const { return buffer.begin(); }
const_iterator end() const { return buffer.end(); }
private:
void check_limits( size_type h, size_type v ) const {
if ( h >= h_limit || v >= v_limit ) throw std::out_of_range(
"Matrix" );
}
U buffer;
size_type h_limit, v_limit;
};
========== ========== ========== ========== ========== ==========

To use the above simply:

Matrix<float> gxy( 10000, 10000 );
float value = gxy( 234, 543 );
assert( value == 0 );
Jul 22 '05 #3

P: n/a
De****@NoSpam.com wrote:
I would like to dynamically allocate in a sub a 2 dimensional Array


One way to do this, although not as safe or efficient as using a class,
is to allocate an array of arrays:

template <typename T>
T** new2D(int numRows, int numCols) {
T** a = new T*[numRows];
for(int i=0; i<numRows; i++) {
a[i] = new T[numCols];
}
}

You then index it like this:
a[row][col]

--
Derrick Coetzee
I grant this newsgroup posting into the public domain. I disclaim all
express or implied warranty and all liability. I am not a professional.
Jul 22 '05 #4

P: n/a
Thanks Daniel.

Your example teaches me a lot about classes.

I've some work to do to understand it completely !

Dennis

"Daniel T." <po********@eathlink.net> wrote:
In article <47********************************@4ax.com>,
De****@NoSpam.com wrote:
I would like to dynamically allocate in a sub a 2 dimensional Array

float *myarray = new float [n][n];

of course I get an error. How do you allocate a 2D array using the New
operator?


Use a class:
========== ========== ========== ========== ========== ==========

template < typename T, typename U = std::deque< T > >
class Matrix {
public:
typedef typename U::size_type size_type;
typedef typename U::reference reference;
typedef typename U::const_reference const_reference;
typedef typename U::iterator iterator;
typedef typename U::const_iterator const_iterator;

Matrix(): h_limit( 0 ), v_limit( 0 ) { }
Matrix( size_type h, size_type v ): buffer( h * v ), h_limit( h ),
v_limit( v ) { }

reference operator()( size_type h, size_type v ) {
check_limits( h, v );
return buffer[h_limit * h + v];
}

const_reference operator()( size_type h, size_type v ) const {
check_limits( h, v );
return buffer[h_limit * h + v];
}

iterator begin() { return buffer.begin(); }
iterator end() { return buffer.end(); }
const_iterator begin() const { return buffer.begin(); }
const_iterator end() const { return buffer.end(); }
private:
void check_limits( size_type h, size_type v ) const {
if ( h >= h_limit || v >= v_limit ) throw std::out_of_range(
"Matrix" );
}
U buffer;
size_type h_limit, v_limit;
};
========== ========== ========== ========== ========== ==========

To use the above simply:

Matrix<float> gxy( 10000, 10000 );
float value = gxy( 234, 543 );
assert( value == 0 );


Jul 22 '05 #5

P: n/a
Derrick Coetzee wrote:
De****@NoSpam.com wrote:
I would like to dynamically allocate in a sub a 2 dimensional Array

One way to do this, although not as safe or efficient as using a class,
is to allocate an array of arrays:

template <typename T>
T** new2D(int numRows, int numCols) {
T** a = new T*[numRows];
for(int i=0; i<numRows; i++) {
a[i] = new T[numCols];
}
}

You then index it like this:
a[row][col]


But the data in the 2D vector isn't contiguous.

template <typename T>
T** new2D(int rows, int cols))
{
T* v = new T[rows * cols];
T** p = new T*[rows];
for (int j = 0 ; j < rows; ++j)
p[j] = v + (j * cols);
return p;
}

Still accessed the same way, and deletion is easier:

delete[] &v[0][0];
delete[] v;

Jul 22 '05 #6

P: n/a
Thanks Derrick,

Interesting solution to the 2D problem using pointers.

If I put this into a DLL sub and I don't delete it. When the Dll is unloaded
will the storage of the 2d array be free'd?

Dennis

Derrick Coetzee <dc****@moonflare.com> wrote:
De****@NoSpam.com wrote:
I would like to dynamically allocate in a sub a 2 dimensional Array


One way to do this, although not as safe or efficient as using a class,
is to allocate an array of arrays:

template <typename T>
T** new2D(int numRows, int numCols) {
T** a = new T*[numRows];
for(int i=0; i<numRows; i++) {
a[i] = new T[numCols];
}
}

You then index it like this:
a[row][col]


Jul 22 '05 #7

P: n/a
Hi Mike,

Thanks for the URL.

One way to dynamically allocate a 1D array in a sub and not have to make it
global so that you can use the array values on the next entry into the sub is:

float MySub(int N){
.....
static float *myarray;
static long lEntry=0;
.....
lEntry++;
if lEntry==1 { myarray = new float [N]; }
"Mike Wahler" <mk******@mkwahler.net> wrote:

<De****@NoSpam.com> wrote in message
news:47********************************@4ax.com.. .
I would like to dynamically allocate in a sub a 2 dimensional Array

float *myarray = new float [n][n];

of course I get an error. How do you allocate a 2D array using the New
operator?


http://www.parashift.com/c++-faq-lit...html#faq-16.15
I currently use

static float gxy[10000][10000];

but I don't want my array in the sub to use up my stack space.

Also does the New operator automatically make the values in the array

static if
the array pointer is never deleted when the sub is ended?


No. An object can have one of three 'storage durations':
automatic, static, or allocated. 'new' allocates an object,
and the object 'lives' until specifically deallocated with
'delete', or the program terminates.
That is I only
allocate the array once the first time I enter the sub. All subsequent

sub
calls skip the array allocation section and use the array pointer that was
allocated in the first sub call. The pointer and values in the array are

not
touched when the sub ends?


See above.

-Mike


Jul 22 '05 #8

P: n/a

<De****@NoSpam.com> wrote in message
news:d7********************************@4ax.com...
Thanks Derrick,

Interesting solution to the 2D problem using pointers.

If I put this into a DLL sub and I don't delete it. When the Dll is unloaded will the storage of the 2d array be free'd?


That depends upon your implementation and platform, the language
does not specify. I wouldn't depend upon it. I advise the 'rule
of thumb': if you allocate it, deallocate it when you're done with
it. Then nothing is left to chance.

BTW please don't top-post.
-Mike
Jul 22 '05 #9

P: n/a
"Mike Wahler" <mk******@mkwahler.net> wrote:

<De****@NoSpam.com> wrote in message
news:d7********************************@4ax.com.. .
Thanks Derrick,

Interesting solution to the 2D problem using pointers.

If I put this into a DLL sub and I don't delete it. When the Dll is

unloaded
will the storage of the 2d array be free'd?


That depends upon your implementation and platform, the language
does not specify. I wouldn't depend upon it. I advise the 'rule
of thumb': if you allocate it, deallocate it when you're done with
it. Then nothing is left to chance.

BTW please don't top-post.
-Mike

Mike,

Deallocating the array is the problem. Another App, which I have not control
over, loads my DLL and calls the subs 10000's of times. I have no way of knowing
when the App has finished with my DLL until it unloads it. I don't want to use
stack space, I need to save the values in the array between calls, and I don't
know what the initial array memory requirements are going to be until the first
call of the sub. I know if I set up global arrays then the mem is freed upon
unloading. But global arrays are not dynamic and must be fixed. So the static
*myarray solution was proposed.
Jul 22 '05 #10

P: n/a
<De****@NoSpam.com> wrote in message
news:c5********************************@4ax.com...
Mike,

Deallocating the array is the problem. Another App, which I have not

control over, loads my DLL and calls the subs 10000's of times. I have no way of knowing when the App has finished with my DLL until it unloads it. I don't want to use stack space, I need to save the values in the array between calls, and I don't know what the initial array memory requirements are going to be until the first call of the sub. I know if I set up global arrays then the mem is freed upon unloading. But global arrays are not dynamic and must be fixed. So the static *myarray solution was proposed.


Well, I'm far from a 'DLL expert', so I won't attempt to advise you
about that. But I suggest you take this issue to
comp.os.ms-windows.programmer.win32, where the Win32 experts
hang out.

-Mike
Jul 22 '05 #11

P: n/a
In article <62********************************@4ax.com>,
De****@NoSpam.com wrote:
Thanks Daniel.

Your example teaches me a lot about classes.

I've some work to do to understand it completely !
Let me present a simpler class that does the same thing, but isn't as
flexable:

template < typename T >
class Matrix {
void check_limits( size_type h, size_type v ) const {
if ( h >= h_limit || v >= v_limit )
throw std::out_of_range( "Matrix" );
}
std::deque<T> buffer;
unsigned h_limit, v_limit;
public:
Matrix():
h_limit( 0 ),
v_limit( 0 ) { }
Matrix( unsigned h, unsigned v ):
buffer( h * v ),
h_limit( h ),
v_limit( v ) { }
T& cell_at( unsigned h, unsigned v ) {
check_limits();
return buffer[ h_limit * h + v ];
}
const T& cell_at( unsigned h, unsigned v ) const {
check_limits();
return buffer[ h_limit * h + v ];
}
};

use it like this:

Matrix<float> m( 100, 100 )
assert( m.cell_at( 12, 5 ) == 0 );
m.cell_at( 12, 5 ) = 9;
assert( m.cell_at( 12, 5 ) == 9 );
"Daniel T." <po********@eathlink.net> wrote:
In article <47********************************@4ax.com>,
De****@NoSpam.com wrote:
I would like to dynamically allocate in a sub a 2 dimensional Array

float *myarray = new float [n][n];

of course I get an error. How do you allocate a 2D array using the New
operator?


Use a class:
========== ========== ========== ========== ========== ==========

template < typename T, typename U = std::deque< T > >
class Matrix {
public:
typedef typename U::size_type size_type;
typedef typename U::reference reference;
typedef typename U::const_reference const_reference;
typedef typename U::iterator iterator;
typedef typename U::const_iterator const_iterator;

Matrix(): h_limit( 0 ), v_limit( 0 ) { }
Matrix( size_type h, size_type v ): buffer( h * v ), h_limit( h ),
v_limit( v ) { }

reference operator()( size_type h, size_type v ) {
check_limits( h, v );
return buffer[h_limit * h + v];
}

const_reference operator()( size_type h, size_type v ) const {
check_limits( h, v );
return buffer[h_limit * h + v];
}

iterator begin() { return buffer.begin(); }
iterator end() { return buffer.end(); }
const_iterator begin() const { return buffer.begin(); }
const_iterator end() const { return buffer.end(); }
private:
void check_limits( size_type h, size_type v ) const {
if ( h >= h_limit || v >= v_limit ) throw std::out_of_range(
"Matrix" );
}
U buffer;
size_type h_limit, v_limit;
};
========== ========== ========== ========== ========== ==========

To use the above simply:

Matrix<float> gxy( 10000, 10000 );
float value = gxy( 234, 543 );
assert( value == 0 );

Jul 22 '05 #12

P: n/a
Thanks again Daniel.

It looks like I'm going to have to buy and study some of those books recommended
by Mike Tyndell to completely understand these two examples.

Dennis

"Daniel T." <po********@eathlink.net> wrote:
In article <62********************************@4ax.com>,
De****@NoSpam.com wrote:
Thanks Daniel.

Your example teaches me a lot about classes.

I've some work to do to understand it completely !


Let me present a simpler class that does the same thing, but isn't as
flexable:

template < typename T >
class Matrix {
void check_limits( size_type h, size_type v ) const {
if ( h >= h_limit || v >= v_limit )
throw std::out_of_range( "Matrix" );
}
std::deque<T> buffer;
unsigned h_limit, v_limit;
public:
Matrix():
h_limit( 0 ),
v_limit( 0 ) { }
Matrix( unsigned h, unsigned v ):
buffer( h * v ),
h_limit( h ),
v_limit( v ) { }
T& cell_at( unsigned h, unsigned v ) {
check_limits();
return buffer[ h_limit * h + v ];
}
const T& cell_at( unsigned h, unsigned v ) const {
check_limits();
return buffer[ h_limit * h + v ];
}
};

use it like this:

Matrix<float> m( 100, 100 )
assert( m.cell_at( 12, 5 ) == 0 );
m.cell_at( 12, 5 ) = 9;
assert( m.cell_at( 12, 5 ) == 9 );
"Daniel T." <po********@eathlink.net> wrote:
>In article <47********************************@4ax.com>,
> De****@NoSpam.com wrote:
>
>> I would like to dynamically allocate in a sub a 2 dimensional Array
>>
>> float *myarray = new float [n][n];
>>
>> of course I get an error. How do you allocate a 2D array using the New
>> operator?
>
>Use a class:
>========== ========== ========== ========== ========== ==========
>
> template < typename T, typename U = std::deque< T > >
>class Matrix {
>public:
> typedef typename U::size_type size_type;
> typedef typename U::reference reference;
> typedef typename U::const_reference const_reference;
> typedef typename U::iterator iterator;
> typedef typename U::const_iterator const_iterator;
>
> Matrix(): h_limit( 0 ), v_limit( 0 ) { }
> Matrix( size_type h, size_type v ): buffer( h * v ), h_limit( h ),
>v_limit( v ) { }
>
> reference operator()( size_type h, size_type v ) {
> check_limits( h, v );
> return buffer[h_limit * h + v];
> }
>
> const_reference operator()( size_type h, size_type v ) const {
> check_limits( h, v );
> return buffer[h_limit * h + v];
> }
>
> iterator begin() { return buffer.begin(); }
> iterator end() { return buffer.end(); }
> const_iterator begin() const { return buffer.begin(); }
> const_iterator end() const { return buffer.end(); }
>
>
>private:
> void check_limits( size_type h, size_type v ) const {
> if ( h >= h_limit || v >= v_limit ) throw std::out_of_range(
>"Matrix" );
> }
> U buffer;
> size_type h_limit, v_limit;
>};
>========== ========== ========== ========== ========== ==========
>
>To use the above simply:
>
>Matrix<float> gxy( 10000, 10000 );
>float value = gxy( 234, 543 );
>assert( value == 0 );


Jul 22 '05 #13

P: n/a
"Mike Wahler" <mk******@mkwahler.net> wrote:
<De****@NoSpam.com> wrote in message
news:c5********************************@4ax.com.. .
>

Mike,

Deallocating the array is the problem. Another App, which I have not

control
over, loads my DLL and calls the subs 10000's of times. I have no way of

knowing
when the App has finished with my DLL until it unloads it. I don't want to

use
stack space, I need to save the values in the array between calls, and I

don't
know what the initial array memory requirements are going to be until the

first
call of the sub. I know if I set up global arrays then the mem is freed

upon
unloading. But global arrays are not dynamic and must be fixed. So the

static
*myarray solution was proposed.


Well, I'm far from a 'DLL expert', so I won't attempt to advise you
about that. But I suggest you take this issue to
comp.os.ms-windows.programmer.win32, where the Win32 experts
hang out.

-Mike

Mike.

This is just what NeilB plus others said (accept Alf P. Steinbach who agreed
with me that this was a C++ lang topic and quoted 3.6.2/3 to prove it) when on
3/14/03 I sent the post entitled "Initialize Global Array in DLL before DLL
Functions are Called?"

Once again you are shifting the burden when you can't answer the question.

Dennis

Jul 22 '05 #14

P: n/a
* De****@NoSpam.com:
* Mike Wahler:
* De****@NoSpam.com:

Deallocating the array is the problem. Another App, which I have not
control over, loads my DLL and calls the subs 10000's of times. I have
no way of knowing when the App has finished with my DLL until it unloads
it. I don't want to use stack space, I need to save the values in the
array between calls, and I don't know what the initial array memory
requirements are going to be until the first call of the sub. I know if
I set up global arrays then the mem is freed upon unloading. But global
arrays are not dynamic and must be fixed. So the static *myarray solution
was proposed.


Well, I'm far from a 'DLL expert', so I won't attempt to advise you
about that. But I suggest you take this issue to
comp.os.ms-windows.programmer.win32, where the Win32 experts
hang out.


This is just what NeilB plus others said (accept Alf P. Steinbach who agreed
with me that this was a C++ lang topic and quoted 3.6.2/3 to prove it) when on
3/14/03 I sent the post entitled "Initialize Global Array in DLL before DLL
Functions are Called?"


I take it you're referring to <url:
http://groups.google.com/groups?selm=3e72cdfc.243200828%40news.bluecom.no>.

The question above is a bit different but 3.6.2/3 (assuming you've quoted
that paragraph identifier correctly) still applies for the creation part.

Namely, you can use a static smart-pointer object, which is guaranteed
to be initialized before the first call of a DLL function, and you simply
store a pointer to a suitable array in that smart-pointer on first call
of your "sub" (by the way, such things are called "functions" in C++).

Regarding guaranteed call of that smart-pointer's destructor on "unloading"
of the DLL, well, I'm too lazy to check it out, but I have a suspicion that
it isn't guaranteed by the C++ standard since there's no such thing as
"unloading" of code in C++ -- and so regarding that aspect I agree with
Mike that you're probably better served by asking in a Windows or
compiler-specific group (the group Mike mentioned is a good Windows one).

Somebody check the standard... ?

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Jul 22 '05 #15

P: n/a
al***@start.no (Alf P. Steinbach) wrote:
* De****@NoSpam.com:
* Mike Wahler:
> * De****@NoSpam.com:
> >
> > Deallocating the array is the problem. Another App, which I have not
> > control over, loads my DLL and calls the subs 10000's of times. I have
> > no way of knowing when the App has finished with my DLL until it unloads
> > it. I don't want to use stack space, I need to save the values in the
> > array between calls, and I don't know what the initial array memory
> > requirements are going to be until the first call of the sub. I know if
> > I set up global arrays then the mem is freed upon unloading. But global
> > arrays are not dynamic and must be fixed. So the static *myarray solution
> > was proposed.
>
>Well, I'm far from a 'DLL expert', so I won't attempt to advise you
>about that. But I suggest you take this issue to
>comp.os.ms-windows.programmer.win32, where the Win32 experts
>hang out.
<--snip-->
Regarding guaranteed call of that smart-pointer's destructor on "unloading"
of the DLL, well, I'm too lazy to check it out, but I have a suspicion that
it isn't guaranteed by the C++ standard since there's no such thing as
"unloading" of code in C++ -- and so regarding that aspect I agree with
Mike that you're probably better served by asking in a Windows or
compiler-specific group (the group Mike mentioned is a good Windows one).

Pushing this query to comp.os.ms-windows.programmer.win32 escapes a C++ Lang
question that is used everyday in c++ programs in the financial community.

For instance suppose you have an algorithm that needs the last 10,000 prices of
a process that's delivering 200 prices a second. The algo runs all day and the
program is closed at the end of the day. The main routine calls a function in
another users DLL at every new price. In that DLL the memory required to save
the last "x" prices is variable and defined by the first call to the function in
that DLL. The user might want to calculate the function on the last 1000 or
50000 or maybe 100,000 prices on each call to the function on every tick. The
Main calls the function on each new price. The 10,000 prices are updated by
deleting the first price and moving the 9999 prices back 1 space and adding the
latest price to the end(a circular array) and a new calculation is done and
passed to the Main. The function has to dynamical allocate static memory on the
heap. Global memory requires fixed storage and is not dynamic. Thus if the
Static float *myarray .....myarray=new float[N] is used inside the function as
in my previous example I think it is the balleywick of the C++ lang to define
whether or not the memory is freed when the DLL is unloaded by main without a
delete[] in the function.

Jul 22 '05 #16

P: n/a
* De****@NoSpam.com:
Pushing this query to comp.os.ms-windows.programmer.win32 escapes a C++ Lang
question that is used everyday in c++ programs in the financial community.
I doubt that.

For instance suppose you have an algorithm that needs the last 10,000 prices of
a process that's delivering 200 prices a second. The algo runs all day and the
program is closed at the end of the day. The main routine calls a function in
another users DLL at every new price. In that DLL the memory required to save
the last "x" prices is variable and defined by the first call to the function in
that DLL. The user might want to calculate the function on the last 1000 or
50000 or maybe 100,000 prices on each call to the function on every tick. The
Main calls the function on each new price. The 10,000 prices are updated by
deleting the first price and moving the 9999 prices back 1 space and adding the
latest price to the end(a circular array) and a new calculation is done and
passed to the Main. The function has to dynamical allocate static memory on the
heap. Global memory requires fixed storage and is not dynamic. Thus if the
Static float *myarray .....myarray=new float[N] is used inside the function as
in my previous example I think it is the balleywick of the C++ lang to define
whether or not the memory is freed when the DLL is unloaded by main without a
delete[] in the function.


Not sure what you mean, but if the DLL is not dynamically unloaded then
there is no problem (you have ordinary C++ rules of destruction in opposite
order of construction, and a std::vector will do), and if it is dynamically
unloaded then you can either go the OS/compiler-specific route (ask about
that in an appropriate newsgroup), or you can inflict some design on the
code, e.g. giving client code responsibility for allocation & deallocation.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Jul 22 '05 #17

P: n/a
In article <ru********************************@4ax.com>,
De****@NoSpam.com wrote:
"Daniel T." <po********@eathlink.net> wrote:
In article <62********************************@4ax.com>,
De****@NoSpam.com wrote:
Thanks Daniel.

Your example teaches me a lot about classes.

I've some work to do to understand it completely !
Let me present a simpler class that does the same thing, but isn't as
flexable:

template < typename T >
class Matrix {
void check_limits( unsigned h, unsigned v ) const {
if ( h >= h_limit || v >= v_limit )
throw std::out_of_range( "Matrix" );
}
std::deque<T> buffer;
unsigned h_limit, v_limit;
public:
Matrix():
h_limit( 0 ),
v_limit( 0 ) { }
Matrix( unsigned h, unsigned v ):
buffer( h * v ),
h_limit( h ),
v_limit( v ) { }
T& cell_at( unsigned h, unsigned v ) {
check_limits();
return buffer[ h_limit * h + v ];
}
const T& cell_at( unsigned h, unsigned v ) const {
check_limits();
return buffer[ h_limit * h + v ];
}
};

use it like this:

Matrix<float> m( 100, 100 )
assert( m.cell_at( 12, 5 ) == 0 );
m.cell_at( 12, 5 ) = 9;
assert( m.cell_at( 12, 5 ) == 9 );

Thanks again Daniel.

It looks like I'm going to have to buy and study some of those books
recommended
by Mike Tyndell to completely understand these two examples.


Which method(s) are you having trouble understanding?

check_limits(unsigned h, unsigned v): checks to make sure that h & v
represent a cell in the Matrix.

Matrix(): creates an empty (0 x 0) matrix.

Matrix(unsigned h, unsigned v): creates and initializes all the elements
in an h x v matrix.

cell_at(unsigned h, unsigned v): returns a modifiable reference to a
cell in the matrix.

cell_at(unsigned h, unsigned v) const: returns an unmodifiable reference
to a cell in the matrix.

The matrix is actually held in an array (a deque in this case, but it
could as easily be held in a vector.) Something like this:

00 10 20
01 11 21
02 12 22

is held in the array like this:

00 10 20 01 11 21 02 12 22

Get it now?
Jul 22 '05 #18

P: n/a
>> > template < typename T >
>class Matrix {
> void check_limits( unsigned h, unsigned v ) const {
> if ( h >= h_limit || v >= v_limit )
> throw std::out_of_range( "Matrix" );
> }
> std::deque<T> buffer;
> unsigned h_limit, v_limit;
>public:
> Matrix():
> h_limit( 0 ),
> v_limit( 0 ) { }
> Matrix( unsigned h, unsigned v ):
> buffer( h * v ),
> h_limit( h ),
> v_limit( v ) { }
> T& cell_at( unsigned h, unsigned v ) {
> check_limits();
> return buffer[ h_limit * h + v ];
> }
> const T& cell_at( unsigned h, unsigned v ) const {
> check_limits();
> return buffer[ h_limit * h + v ];
> }
>};

use it like this:

Matrix<float> m( 100, 100 )
assert( m.cell_at( 12, 5 ) == 0 );
m.cell_at( 12, 5 ) = 9;
assert( m.cell_at( 12, 5 ) == 9 );


Which method(s) are you having trouble understanding?

check_limits(unsigned h, unsigned v): checks to make sure that h & v
represent a cell in the Matrix.

Matrix(): creates an empty (0 x 0) matrix.

Matrix(unsigned h, unsigned v): creates and initializes all the elements
in an h x v matrix.

cell_at(unsigned h, unsigned v): returns a modifiable reference to a
cell in the matrix.

cell_at(unsigned h, unsigned v) const: returns an unmodifiable reference
to a cell in the matrix.

The matrix is actually held in an array (a deque in this case, but it
could as easily be held in a vector.) Something like this:

00 10 20
01 11 21
02 12 22

is held in the array like this:

00 10 20 01 11 21 02 12 22

Thanks again for your explanation.

I'm having trouble understanding:

Where does the function "cell_at" come from.

I'm not to familiar with the use of "std::deque<T> buffer;" where are some good
examples? I checked the help section of vc++6.0 but the deque examples were not
the same.

Why do h and v have to be unsigned?

Why is the "const {" there in
"void check_limits( unsigned h, unsigned v ) const{"
const T& cell_at( unsigned h, unsigned v ) const {

If the class is defined outside the function is "buffer" static when the
function is exited?

Thanks for your time and help in understanding this Class.

Dennis
Jul 22 '05 #19

P: n/a

<De****@NoSpam.com> wrote in message
news:b4********************************@4ax.com...
> template < typename T >
>class Matrix {
> void check_limits( unsigned h, unsigned v ) const {
> if ( h >= h_limit || v >= v_limit )
> throw std::out_of_range( "Matrix" );
> }
> std::deque<T> buffer;
> unsigned h_limit, v_limit;
>public:
> Matrix():
> h_limit( 0 ),
> v_limit( 0 ) { }
> Matrix( unsigned h, unsigned v ):
> buffer( h * v ),
> h_limit( h ),
> v_limit( v ) { }
> T& cell_at( unsigned h, unsigned v ) {
> check_limits();
> return buffer[ h_limit * h + v ];
> }
> const T& cell_at( unsigned h, unsigned v ) const {
> check_limits();
> return buffer[ h_limit * h + v ];
> }
>};
use it like this:

Matrix<float> m( 100, 100 )
assert( m.cell_at( 12, 5 ) == 0 );
m.cell_at( 12, 5 ) = 9;
assert( m.cell_at( 12, 5 ) == 9 );
Which method(s) are you having trouble understanding?

check_limits(unsigned h, unsigned v): checks to make sure that h & v
represent a cell in the Matrix.

Matrix(): creates an empty (0 x 0) matrix.

Matrix(unsigned h, unsigned v): creates and initializes all the elements
in an h x v matrix.

cell_at(unsigned h, unsigned v): returns a modifiable reference to a
cell in the matrix.

cell_at(unsigned h, unsigned v) const: returns an unmodifiable reference
to a cell in the matrix.

The matrix is actually held in an array (a deque in this case, but it
could as easily be held in a vector.) Something like this:

00 10 20
01 11 21
02 12 22

is held in the array like this:

00 10 20 01 11 21 02 12 22

Thanks again for your explanation.

I'm having trouble understanding:

Where does the function "cell_at" come from.


It came from Daniel, he wrote it. I suspect he used
the name 'cell_at' to mimic the name of a similar
member function from the standard class 'std::vector'.
The vector class has a subscript operator ( [] ) that
works just like with an array, but also like an array
is not bounds checked. It also has a element-access
function which does do bounds checking, called 'at()'.
So he came up with 'cell_at()' for the name.

I'm not to familiar with the use of "std::deque<T> buffer;"
'std::queue' is one of several 'container' classes provided
by the C++ standard library. It's a templated class (as
are all the containers), with the template parameter 'T'
specifying the actual type of the elements stored in it.

e.g.

std::deque<int> di; /* a deque container which can store objects of
type 'int' */
where are some good
examples?
I don't know of any online, but a good textbook should have some.
The most recommended book on the standard library is:
www.josuttis.com/libbook I *highly* recommend it.
I checked the help section of vc++6.0 but the deque examples were not
the same.

Why do h and v have to be unsigned?
They don't *have* to be, but it makes sense for them to be.
A signed type would allow for negative values (and only has
half the value range of the corresponding unsigned type).
But what would a negative size or index *mean*? Also note that
'h' and 'v' shouldn't really be just any unsigned type, but type
'size_t', which is an (implementation-defined) unsigned type which
is guaranteed to be able to hold the largest possible sized object
(or the largest number of one-byte objects). Actually it should
have the same type as the container class ('deque' in this case)'s
'size_type' type. But I suppose allowing for that would make the
code even harder for you to follow. :-)

Why is the "const {" there in
"void check_limits( unsigned h, unsigned v ) const{"
const T& cell_at( unsigned h, unsigned v ) const {
Look up 'const member function'. The 'const' after the
parameter list is a 'promise' to the compiler that the
function will not modify the object for which it was called.
If you write code that tries to do so, you'll get a compile
error.

If the class is defined outside the function
The class is defined outside any function (as it should be).
is "buffer" static when the
function is exited?


What function? Anyway, an object will have static storage duration
in two cases:

1. It's defined at file scope (outside any function or class)
2. It's specifically qualified with the 'static' keyword.

-Mike
Jul 22 '05 #20

P: n/a

<De****@NoSpam.com> wrote in message
news:b4********************************@4ax.com...
> template < typename T >
>class Matrix {
> void check_limits( unsigned h, unsigned v ) const {
> if ( h >= h_limit || v >= v_limit )
> throw std::out_of_range( "Matrix" );
> }
> std::deque<T> buffer;
> unsigned h_limit, v_limit;
>public:
> Matrix():
> h_limit( 0 ),
> v_limit( 0 ) { }
> Matrix( unsigned h, unsigned v ):
> buffer( h * v ),
> h_limit( h ),
> v_limit( v ) { }
> T& cell_at( unsigned h, unsigned v ) {
> check_limits();
> return buffer[ h_limit * h + v ];
> }
> const T& cell_at( unsigned h, unsigned v ) const {
> check_limits();
> return buffer[ h_limit * h + v ];
> }
>};
use it like this:

Matrix<float> m( 100, 100 )
assert( m.cell_at( 12, 5 ) == 0 );
m.cell_at( 12, 5 ) = 9;
assert( m.cell_at( 12, 5 ) == 9 );
Which method(s) are you having trouble understanding?

check_limits(unsigned h, unsigned v): checks to make sure that h & v
represent a cell in the Matrix.

Matrix(): creates an empty (0 x 0) matrix.

Matrix(unsigned h, unsigned v): creates and initializes all the elements
in an h x v matrix.

cell_at(unsigned h, unsigned v): returns a modifiable reference to a
cell in the matrix.

cell_at(unsigned h, unsigned v) const: returns an unmodifiable reference
to a cell in the matrix.

The matrix is actually held in an array (a deque in this case, but it
could as easily be held in a vector.) Something like this:

00 10 20
01 11 21
02 12 22

is held in the array like this:

00 10 20 01 11 21 02 12 22

Thanks again for your explanation.

I'm having trouble understanding:

Where does the function "cell_at" come from.


It came from Daniel, he wrote it. I suspect he used
the name 'cell_at' to mimic the name of a similar
member function from the standard class 'std::vector'.
The vector class has a subscript operator ( [] ) that
works just like with an array, but also like an array
is not bounds checked. It also has a element-access
function which does do bounds checking, called 'at()'.
So he came up with 'cell_at()' for the name.

I'm not to familiar with the use of "std::deque<T> buffer;"
'std::queue' is one of several 'container' classes provided
by the C++ standard library. It's a templated class (as
are all the containers), with the template parameter 'T'
specifying the actual type of the elements stored in it.

e.g.

std::deque<int> di; /* a deque container which can store objects of
type 'int' */
where are some good
examples?
I don't know of any online, but a good textbook should have some.
The most recommended book on the standard library is:
www.josuttis.com/libbook I *highly* recommend it.
I checked the help section of vc++6.0 but the deque examples were not
the same.

Why do h and v have to be unsigned?
They don't *have* to be, but it makes sense for them to be.
A signed type would allow for negative values (and only has
half the value range of the corresponding unsigned type).
But what would a negative size or index *mean*? Also note that
'h' and 'v' shouldn't really be just any unsigned type, but type
'size_t', which is an (implementation-defined) unsigned type which
is guaranteed to be able to hold the largest possible sized object
(or the largest number of one-byte objects). Actually it should
have the same type as the container class ('deque' in this case)'s
'size_type' type. But I suppose allowing for that would make the
code even harder for you to follow. :-)

Why is the "const {" there in
"void check_limits( unsigned h, unsigned v ) const{"
const T& cell_at( unsigned h, unsigned v ) const {
Look up 'const member function'. The 'const' after the
parameter list is a 'promise' to the compiler that the
function will not modify the object for which it was called.
If you write code that tries to do so, you'll get a compile
error.

If the class is defined outside the function
The class is defined outside any function (as it should be).
is "buffer" static when the
function is exited?


What function? Anyway, an object will have static storage duration
in two cases:

1. It's defined at file scope (outside any function or class)
2. It's specifically qualified with the 'static' keyword.

-Mike
Jul 22 '05 #21

P: n/a
Thanks Mike that helped and I learned a lot.

Dennis

"Mike Wahler" <mk******@mkwahler.net> wrote:

<De****@NoSpam.com> wrote in message
news:b4********************************@4ax.com.. .
>> > template < typename T >
>> >class Matrix {
>> > void check_limits( unsigned h, unsigned v ) const {
>> > if ( h >= h_limit || v >= v_limit )
>> > throw std::out_of_range( "Matrix" );
>> > }
>> > std::deque<T> buffer;
>> > unsigned h_limit, v_limit;
>> >public:
>> > Matrix():
>> > h_limit( 0 ),
>> > v_limit( 0 ) { }
>> > Matrix( unsigned h, unsigned v ):
>> > buffer( h * v ),
>> > h_limit( h ),
>> > v_limit( v ) { }
>> > T& cell_at( unsigned h, unsigned v ) {
>> > check_limits();
>> > return buffer[ h_limit * h + v ];
>> > }
>> > const T& cell_at( unsigned h, unsigned v ) const {
>> > check_limits();
>> > return buffer[ h_limit * h + v ];
>> > }
>> >};
> >use it like this:
> >
> >Matrix<float> m( 100, 100 )
> >assert( m.cell_at( 12, 5 ) == 0 );
> >m.cell_at( 12, 5 ) = 9;
> >assert( m.cell_at( 12, 5 ) == 9 );
>
>Which method(s) are you having trouble understanding?
>
>check_limits(unsigned h, unsigned v): checks to make sure that h & v
>represent a cell in the Matrix.
>
>Matrix(): creates an empty (0 x 0) matrix.
>
>Matrix(unsigned h, unsigned v): creates and initializes all the elements
>in an h x v matrix.
>
>cell_at(unsigned h, unsigned v): returns a modifiable reference to a
>cell in the matrix.
>
>cell_at(unsigned h, unsigned v) const: returns an unmodifiable reference
>to a cell in the matrix.
>
>The matrix is actually held in an array (a deque in this case, but it
>could as easily be held in a vector.) Something like this:
>
>00 10 20
>01 11 21
>02 12 22
>
>is held in the array like this:
>
>00 10 20 01 11 21 02 12 22
>

Thanks again for your explanation.

I'm having trouble understanding:

Where does the function "cell_at" come from.


It came from Daniel, he wrote it. I suspect he used
the name 'cell_at' to mimic the name of a similar
member function from the standard class 'std::vector'.
The vector class has a subscript operator ( [] ) that
works just like with an array, but also like an array
is not bounds checked. It also has a element-access
function which does do bounds checking, called 'at()'.
So he came up with 'cell_at()' for the name.

I'm not to familiar with the use of "std::deque<T> buffer;"


'std::queue' is one of several 'container' classes provided
by the C++ standard library. It's a templated class (as
are all the containers), with the template parameter 'T'
specifying the actual type of the elements stored in it.

e.g.

std::deque<int> di; /* a deque container which can store objects of
type 'int' */
where are some good
examples?


I don't know of any online, but a good textbook should have some.
The most recommended book on the standard library is:
www.josuttis.com/libbook I *highly* recommend it.
I checked the help section of vc++6.0 but the deque examples were not
the same.

Why do h and v have to be unsigned?


They don't *have* to be, but it makes sense for them to be.
A signed type would allow for negative values (and only has
half the value range of the corresponding unsigned type).
But what would a negative size or index *mean*? Also note that
'h' and 'v' shouldn't really be just any unsigned type, but type
'size_t', which is an (implementation-defined) unsigned type which
is guaranteed to be able to hold the largest possible sized object
(or the largest number of one-byte objects). Actually it should
have the same type as the container class ('deque' in this case)'s
'size_type' type. But I suppose allowing for that would make the
code even harder for you to follow. :-)

Why is the "const {" there in
"void check_limits( unsigned h, unsigned v ) const{"
const T& cell_at( unsigned h, unsigned v ) const {


Look up 'const member function'. The 'const' after the
parameter list is a 'promise' to the compiler that the
function will not modify the object for which it was called.
If you write code that tries to do so, you'll get a compile
error.

If the class is defined outside the function


The class is defined outside any function (as it should be).
is "buffer" static when the
function is exited?


What function? Anyway, an object will have static storage duration
in two cases:

1. It's defined at file scope (outside any function or class)
2. It's specifically qualified with the 'static' keyword.

-Mike


Jul 22 '05 #22

P: n/a
In article <b4********************************@4ax.com>,
De****@NoSpam.com wrote:
> template < typename T >
>class Matrix {
> void check_limits( unsigned h, unsigned v ) const {
> if ( h >= h_limit || v >= v_limit )
> throw std::out_of_range( "Matrix" );
> }
> std::deque<T> buffer;
> unsigned h_limit, v_limit;
>public:
> Matrix():
> h_limit( 0 ),
> v_limit( 0 ) { }
> Matrix( unsigned h, unsigned v ):
> buffer( h * v ),
> h_limit( h ),
> v_limit( v ) { }
> T& cell_at( unsigned h, unsigned v ) {
> check_limits();
> return buffer[ h_limit * h + v ];
> }
> const T& cell_at( unsigned h, unsigned v ) const {
> check_limits();
> return buffer[ h_limit * h + v ];
> }
>};
use it like this:

Matrix<float> m( 100, 100 )
assert( m.cell_at( 12, 5 ) == 0 );
m.cell_at( 12, 5 ) = 9;
assert( m.cell_at( 12, 5 ) == 9 );
Which method(s) are you having trouble understanding?

check_limits(unsigned h, unsigned v): checks to make sure that h & v
represent a cell in the Matrix.

Matrix(): creates an empty (0 x 0) matrix.

Matrix(unsigned h, unsigned v): creates and initializes all the elements
in an h x v matrix.

cell_at(unsigned h, unsigned v): returns a modifiable reference to a
cell in the matrix.

cell_at(unsigned h, unsigned v) const: returns an unmodifiable reference
to a cell in the matrix.

The matrix is actually held in an array (a deque in this case, but it
could as easily be held in a vector.) Something like this:

00 10 20
01 11 21
02 12 22

is held in the array like this:

00 10 20 01 11 21 02 12 22

Thanks again for your explanation.

I'm having trouble understanding:

Where does the function "cell_at" come from.


It sounded like a good name, you can call it something different if you
want. Origionally, I used operator(), but I thought cell_at would be
easier for a beginner understand.

I'm not to familiar with the use of "std::deque<T> buffer;" where are some
good
examples? I checked the help section of vc++6.0 but the deque examples were
not
the same.
<http://www.sgi.com/tech/stl/Deque.html>
"""
A deque is very much like a vector: like vector, it is a sequence that
supports random access to elements, constant time insertion and removal
of elements at the end of the sequence, and linear time insertion and
removal of elements in the middle.

The main way in which deque differs from vector is that deque also
supports constant time insertion and removal of elements at the
beginning of the sequence. Additionally, deque does not have any member
functions analogous to vector's capacity() and reserve(), and does not
provide any of the guarantees on iterator validity that are associated
with those member functions.
"""

You might wonder why I used a deque rather than a vector. I did it
because deque's memory doesn't have to be contigious which usually works
better for very large sequences.

Why do h and v have to be unsigned?
What would it mean to create a Matrix that is -5 elements wide?

Why is the "const {" there in
"void check_limits( unsigned h, unsigned v ) const{"
const T& cell_at( unsigned h, unsigned v ) const {
That means that 'this' is a const pointer rather than a normal pointer.
It allows those functions to be called on const objects. For example:

void foo( const Matrix<double>& matrix ) {
double i = matrix.cell_at( 5, 3 );
// the above will call 'cell_at(unsigned, unsigned)const'
// because the matrix cannot be modified.
}

If the class is defined outside the function is "buffer" static when the
function is exited?


The class must be defined outside of any function. Creation of Matrix
objects follows the same rules as any other object or int for that
matter.
Jul 22 '05 #23

P: n/a
al***@start.no (Alf P. Steinbach) wrote:
* De****@NoSpam.com:
Pushing this query to comp.os.ms-windows.programmer.win32 escapes a C++ Lang
question that is used everyday in c++ programs in the financial community.
I doubt that.

<snip>
Not sure what you mean, but if the DLL is not dynamically unloaded then
there is no problem (you have ordinary C++ rules of destruction in opposite
order of construction, and a std::vector will do), and if it is dynamically
unloaded then you can either go the OS/compiler-specific route (ask about
that in an appropriate newsgroup), or you can inflict some design on the
code, e.g. giving client code responsibility for allocation & deallocation.


This IS a C++ lang question and here's why:

Either the C++ compiler cleans up global and static memory created by a function
in a standard DLL when the DLL is unloaded or not!

Simple question that requres a C++ lang answer.

Jul 22 '05 #24

P: n/a
* De****@NoSpam.com:
al***@start.no (Alf P. Steinbach) wrote:
* De****@NoSpam.com:
Pushing this query to comp.os.ms-windows.programmer.win32 escapes a C++ Lang
question that is used everyday in c++ programs in the financial community.


I doubt that.

<snip>

Not sure what you mean, but if the DLL is not dynamically unloaded then
there is no problem (you have ordinary C++ rules of destruction in opposite
order of construction, and a std::vector will do), and if it is dynamically
unloaded then you can either go the OS/compiler-specific route (ask about
that in an appropriate newsgroup), or you can inflict some design on the
code, e.g. giving client code responsibility for allocation & deallocation.


This IS a C++ lang question and here's why:

Either the C++ compiler cleans up global and static memory created by a function
in a standard DLL when the DLL is unloaded or not!

Simple question that requres a C++ lang answer.


It would be nice if the C++ standard acknowledged the existence of
dynamic libraries, threads, and goddamit, linkers.

But it doesn't.

So there's no C++ answer, and the question is not a C++ one except if you
formulate it as a language change proposal and post it in relevant group.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Jul 22 '05 #25

P: n/a

<De****@NoSpam.com> wrote in message
news:82********************************@4ax.com...
al***@start.no (Alf P. Steinbach) wrote:
* De****@NoSpam.com:
Pushing this query to comp.os.ms-windows.programmer.win32 escapes a C++ Lang question that is used everyday in c++ programs in the financial
community.
I doubt that.
<snip>

Not sure what you mean, but if the DLL is not dynamically unloaded then
there is no problem (you have ordinary C++ rules of destruction in oppositeorder of construction, and a std::vector will do), and if it is dynamicallyunloaded then you can either go the OS/compiler-specific route (ask about
that in an appropriate newsgroup), or you can inflict some design on the
code, e.g. giving client code responsibility for allocation &

deallocation.
This IS a C++ lang question and here's why:

Either the C++ compiler cleans up global and static memory created by a function in a standard DLL when the DLL is unloaded or not!

Simple question that requres a C++ lang answer.


Here's why this is NOT a C++ language question:
DLL's are NOT defined by C++. So the language has
NOTHING to say about how a DLL behaves, or affects
applications that use one.

-Mike
Jul 22 '05 #26

P: n/a
In article <82********************************@4ax.com>,
<De****@NoSpam.com> wrote:

This IS a C++ lang question
No, it's not, it's a compiler- and operating-system-specific question.
and here's why: Either the C++ compiler
.... that you are using, under your particular operating system, ...
cleans up global and static
memory created by a function >in a standard DLL when the DLL is unloaded
or not!


What is a "standard DLL", and how can I use one under Unix, MacOS, etc.?

--
Jon Bell <jt*******@presby.edu> Presbyterian College
Dept. of Physics and Computer Science Clinton, South Carolina USA
Jul 22 '05 #27

P: n/a
al***@start.no (Alf P. Steinbach) wrote:

This IS a C++ lang question and here's why:

Either the C++ compiler cleans up global and static memory created by a function
in a standard DLL when the DLL is unloaded or not!

Simple question that requres a C++ lang answer.


It would be nice if the C++ standard acknowledged the existence of
dynamic libraries, threads, and goddamit, linkers.

But it doesn't.

So there's no C++ answer, and the question is not a C++ one except if you
formulate it as a language change proposal and post it in relevant group.


Well let's see. Maybe this is a VC++ lang question?

When I load my VC++ gui, one of the selections it asks me when I click on "New"
is do I want to make a Win32 Dynamic-link Library Project.

If I answer yes then it allows my to set up various C++, .h, etc modules and
then compiles and builds the C++ DLL. I'm sure other C++ compiliers are similar
in their construction of a C++ language DLL.

No I don't get why this is not a C++ question. Granted that different C++
compiliers handle Global memory release generated by functions in a called DLL
differently. Doesn't the C++ Lang define how a DLL is loaded and freed? If so
then it defines what it does when it frees the DLL. I'll bet that MS VC++ has
the majority of C++ programmers in this ng so this question can be answered
here.

Dennis

Jul 22 '05 #28

P: n/a

<De****@NoSpam.com> wrote in message
news:b2********************************@4ax.com...
al***@start.no (Alf P. Steinbach) wrote:

This IS a C++ lang question and here's why:

Either the C++ compiler cleans up global and static memory created by a function in a standard DLL when the DLL is unloaded or not!

Simple question that requres a C++ lang answer.
It would be nice if the C++ standard acknowledged the existence of
dynamic libraries, threads, and goddamit, linkers.

But it doesn't.

So there's no C++ answer, and the question is not a C++ one except if you
formulate it as a language change proposal and post it in relevant group.


Well let's see. Maybe this is a VC++ lang question?


VC++ is not a language, it's an implementation of C++,
which also includes many extensions for working with
Windows. Those extensions (such as keywords for DLL
support) are *not* part of the ISO standard C++ language,
which is the only topic here.
When I load my VC++ gui, one of the selections it asks me when I click on "New" is do I want to make a Win32 Dynamic-link Library Project.

If I answer yes then it allows my to set up various C++, .h, etc modules and then compiles and builds the C++ DLL. I'm sure other C++ compiliers are similar in their construction of a C++ language DLL.
Try asking in a VC++ group. Since you're asking about how to
build from the IDE, the group 'microsoft.public.vc.ide_general'
springs to mind. Another great place for information about
Microsoft products and technologies is www.msdn.microsoft.com
(which btw has a list of newsgroups which discuss their products).
Perhaps if you'd searched for a VC++ group instead of continuing
to insist that VC++ is topical here when it's not, you'd have
solved your problem by now.
No I don't get why this is not a C++ question.
Because you're asking about a particular implementation. Only
the (ISO standard) *language* is topical here. Please see:
http://www.slack.net/~shiva/welcome.txt
... which explains this very clearly.
Granted that different C++
compiliers
There are many different C++ implementations, yes. And many of
them provide 'extensions' for working with their target platforms.
Here, we only discuss what they have in common: the *language*
itself.
handle Global memory release
The C++ language has no notion of 'Global memory' or 'Global memory
release'.
generated by functions in a called DLL
differently. Doesn't the C++ Lang define how a DLL is loaded and freed?
Absolutely not. C++ has no notion of DLL's or shared libraries. DLL's
are a Microsoft invention, for use with the Windows operating system.
ISO standard C++ is a platform-independent language.
If so
It does not.
then it defines what it does when it frees the DLL.
It does not.
I'll bet that MS VC++ has
the majority of C++ programmers in this ng
I seriously doubt that. I cannot know for sure (for example we cannot
know how many folks read here who never post), but were I to hazard
a guess, I'd suspect that g++ was the most widely used by readers/
posters here. But suppose that most folks here do indeed use VC++.
That still doesn't make it topical here, any more than would Ford
automobiles, even if we all drove one.
so this question can be answered
here.


It could be, but anyone who wishes to observe this group's
topicality will not answer. More than one of use has already
done you the courtesy of suggesting a more appropriate group.
You respond by insisting that nontopical material is topical.
That's hardly productive or courteous.
-Mike

Jul 22 '05 #29

P: n/a
"Mike Wahler" <mk******@mkwahler.net> wrote in message
news:xD******************@newsread1.news.pas.earth link.net...

I seriously doubt that. I cannot know for sure (for example we cannot
know how many folks read here who never post), but were I to hazard
a guess, I'd suspect that g++ was the most widely used by readers/
posters here. But suppose that most folks here do indeed use VC++.
That still doesn't make it topical here, any more than would Ford
automobiles, even if we all drove one.


I drive a Ford F150 truck. Is that considered an automobile? And, if so,
is it still OT?

--
Mabden
Jul 22 '05 #30

P: n/a
"Mike Wahler" <mk******@mkwahler.net> wrote:
<snip>
VC++ is not a language, it's an implementation of C++,
which also includes many extensions for working with
Windows. Those extensions (such as keywords for DLL
support) are *not* part of the ISO standard C++ language,
which is the only topic here.
<snip>
No I don't get why this is not a C++ question.


Because you're asking about a particular implementation. Only
the (ISO standard) *language* is topical here. Please see:
http://www.slack.net/~shiva/welcome.txt
.. which explains this very clearly.

<snip>>There are many different C++ implementations, yes. And many of
them provide 'extensions' for working with their target platforms.
Here, we only discuss what they have in common: the *language*
itself. <snip>
-Mike


Ok thanks Mike. You've finally convinced me that this ng is NOT the forum to
answer my DLL global memory question.

I apologize to all members of this ng for taking up your time and I appreciate
your efforts and responses.

Dennis
Jul 22 '05 #31

P: n/a
"Daniel T." <po********@eathlink.net> wrote:
In article <b4********************************@4ax.com>,
De****@NoSpam.com wrote:

template < typename T >
class Matrix {
void check_limits( unsigned h, unsigned v ) const {
if ( h >= h_limit || v >= v_limit )
throw std::out_of_range( "Matrix" );
}
std::deque<T> buffer;
unsigned h_limit, v_limit;public:
Matrix():
h_limit( 0 ),
v_limit( 0 ) { }
Matrix( unsigned h, unsigned v ):
buffer( h * v ),
h_limit( h ),
v_limit( v ) { }
T& cell_at( unsigned h, unsigned v ) {
check_limits();
return buffer[ h_limit * h + v ];
}
const T& cell_at( unsigned h, unsigned v ) const {
check_limits();
return buffer[ h_limit * h + v ];
}
};

Which method(s) are you having trouble understanding?

Daniel it's been a couple of months since you sent this but I had a few more
questions about this Matrix class.

Why when making the function cell_at in the Matrix class why do you define two
cell_at functions? That is why do you need to have:
T& cell_at( unsigned h, unsigned v ) {
check_limits();
return buffer[ h_limit * h + v ];
}
and
const T& cell_at( unsigned h, unsigned v ) const {
check_limits();
return buffer[ h_limit * h + v ];
}
?

Also if I wanted to have a resize ability would I add?:

T& resize( unsigned h, unsigned v ) {
buffer.resize( h * v );
h_limit= h ;
v_limit= v ;
}
would I need a "const" definition of this function also?

Thanks for your help in understanding this .

Dennis
Jul 22 '05 #32

P: n/a
De****@NoSpam.com wrote:
"Daniel T." <po********@eathlink.net> wrote:
In article <b4********************************@4ax.com>,
De****@NoSpam.com wrote:

template < typename T >
class Matrix {
void check_limits( unsigned h, unsigned v ) const {
if ( h >= h_limit || v >= v_limit )
throw std::out_of_range( "Matrix" );
}
std::deque<T> buffer;
unsigned h_limit, v_limit;

public:
Matrix():
h_limit( 0 ),
v_limit( 0 ) { }
Matrix( unsigned h, unsigned v ):
buffer( h * v ),
h_limit( h ),
v_limit( v ) { }
T& cell_at( unsigned h, unsigned v ) {
check_limits();
return buffer[ h_limit * h + v ];
}
const T& cell_at( unsigned h, unsigned v ) const {
check_limits();
return buffer[ h_limit * h + v ];
}
};

Which method(s) are you having trouble understanding?

Daniel it's been a couple of months since you sent this but I had a few more
questions about this Matrix class.

Why when making the function cell_at in the Matrix class why do you define two
cell_at functions? That is why do you need to have:
T& cell_at( unsigned h, unsigned v ) {
check_limits();
return buffer[ h_limit * h + v ];
}
and
const T& cell_at( unsigned h, unsigned v ) const {
check_limits();
return buffer[ h_limit * h + v ];
}
?

Also if I wanted to have a resize ability would I add?:

T& resize( unsigned h, unsigned v ) {
buffer.resize( h * v );
h_limit= h ;
v_limit= v ;
}

Actually the resize function should be

void resize( unsigned h, unsigned v ) {
buffer.resize( h * v );
h_limit= h ;
v_limit= v ;
}

and the Matrix size function should be
long msize( ) { return=buffer.size(); }

Do I need const's for these functions? I don't quite understand the need for
the const in the cell_at and check_limits functions.

Thanks.

Dennis

Jul 22 '05 #33

P: n/a
De****@NoSpam.com wrote:
De****@NoSpam.com wrote:

"Daniel T." <po********@eathlink.net> wrote:

In article <b4********************************@4ax.com>,
De****@NoSpam.com wrote:

template < typename T >
class Matrix {
void check_limits( unsigned h, unsigned v ) const {
if ( h >= h_limit || v >= v_limit )
throw std::out_of_range( "Matrix" );
}
std::deque<T> buffer;

unsigned h_limit, v_limit;

public:
Matrix():
h_limit( 0 ),
v_limit( 0 ) { }
Matrix( unsigned h, unsigned v ):
buffer( h * v ),
h_limit( h ),
v_limit( v ) { }
T& cell_at( unsigned h, unsigned v ) {
check_limits();
return buffer[ h_limit * h + v ];
}
const T& cell_at( unsigned h, unsigned v ) const {
check_limits();
return buffer[ h_limit * h + v ];
}
};
Which method(s) are you having trouble understanding?


Daniel it's been a couple of months since you sent this but I had a few more
questions about this Matrix class.

Why when making the function cell_at in the Matrix class why do you define two
cell_at functions? That is why do you need to have:
T& cell_at( unsigned h, unsigned v ) {
check_limits();
return buffer[ h_limit * h + v ];
}
and
const T& cell_at( unsigned h, unsigned v ) const {
check_limits();
return buffer[ h_limit * h + v ];
}
?
Because they return a reference to a private object. You definitely
don't want to return that to const callers. For example

template <class T>
void f(const Matrix<T> &m)
{
T &cell = m.cell_at(1, 1);

// fiddle with cell, which is a reference so you are
// able to modify the original object.
}

The thing is, m was defined as const so you should not be able to do
that. Having two different versions of these (const and non const)
allows const and non const Matric objects to access the cell they want,
but only non const Matrix objects will be able to modify them.

template <class T>
void f(const Matrix<T> &cm, Matrix<T> &m)
{
T &cell = cm.cell_at(1, 1); // invalid, cannot convert const T&
// to T&

const T &cell = cm.cell_at(1, 1); // ok
cell.fiddle(); // error if fiddle() is not const

T &cell = m.cell_at(1, 1); // always ok
cell.fiddle(); // always ok
}

cm.cell_at() calls Matrix<T>::cell_at() const
Also if I wanted to have a resize ability would I add?:

T& resize( unsigned h, unsigned v ) {
buffer.resize( h * v );
h_limit= h ;
v_limit= v ;
}


Actually the resize function should be

void resize( unsigned h, unsigned v ) {
buffer.resize( h * v );
h_limit= h ;
v_limit= v ;
}

and the Matrix size function should be
long msize( ) { return=buffer.size(); }

Do I need const's for these functions?


Definitely not, since these functions are *not* const.
I don't quite understand the need for
the const in the cell_at and check_limits functions.


A const member function such as

class C
{
public:
void f() const;
};

receives a const this pointer, which means it can only call const member
functions.

class C
{
public:

void const_f() const
{
this->nonconst_f(); // error, since this is of type const C*
}

void nonconst_f()
{
this->const_f(); // ok, since this is of type C*
}
};

You can call const member functions from non const member functions, but
not the other way around.

A member function should be const when it does not modify the visible
state of the object (look up "mutable" for some interesting features).
Examples of const member functions are functions which return by value
or by const reference/pointer (such as length(), size(), state() and
distance()) and non const member functions modify the visible state
(such as resize(), clear(), add() and remove()).

You should definitely read more about that, since const member functions
are a powerful feature for preventing silly programmers (as we all are)
from touching something they shouldn't touch (as we all do).
Jonathan
Jul 22 '05 #34

P: n/a
Jonathan Mcdougall <jo***************@DELyahoo.ca> wrote:
De****@NoSpam.com wrote:

<snip>

Why when making the function cell_at in the Matrix class why do you define two
cell_at functions? That is why do you need to have:
T& cell_at( unsigned h, unsigned v ) {
check_limits();
return buffer[ h_limit * h + v ];
}
and
const T& cell_at( unsigned h, unsigned v ) const {
check_limits();
return buffer[ h_limit * h + v ];
}
?
Because they return a reference to a private object. You definitely
don't want to return that to const callers. For example

template <class T>
void f(const Matrix<T> &m)
{
T &cell = m.cell_at(1, 1);

// fiddle with cell, which is a reference so you are
// able to modify the original object.
}

The thing is, m was defined as const so you should not be able to do
that. Having two different versions of these (const and non const)
allows const and non const Matric objects to access the cell they want,
but only non const Matrix objects will be able to modify them.

template <class T>
void f(const Matrix<T> &cm, Matrix<T> &m)
{
T &cell = cm.cell_at(1, 1); // invalid, cannot convert const T&
// to T&

const T &cell = cm.cell_at(1, 1); // ok
cell.fiddle(); // error if fiddle() is not const

T &cell = m.cell_at(1, 1); // always ok
cell.fiddle(); // always ok
}

cm.cell_at() calls Matrix<T>::cell_at() const
Also if I wanted to have a resize ability would I add?:

T& resize( unsigned h, unsigned v ) {
buffer.resize( h * v );
h_limit= h ;
v_limit= v ;
}


Actually the resize function should be

void resize( unsigned h, unsigned v ) {
buffer.resize( h * v );
h_limit= h ;
v_limit= v ;
}

and the Matrix size function should be
long msize( ) { return=buffer.size(); }

Do I need const's for these functions?


Definitely not, since these functions are *not* const.
I don't quite understand the need for
the const in the cell_at and check_limits functions.


A const member function such as

class C
{
public:
void f() const;
};

receives a const this pointer, which means it can only call const member
functions.

class C
{
public:

void const_f() const
{
this->nonconst_f(); // error, since this is of type const C*
}

void nonconst_f()
{
this->const_f(); // ok, since this is of type C*
}
};

You can call const member functions from non const member functions, but
not the other way around.

A member function should be const when it does not modify the visible
state of the object (look up "mutable" for some interesting features).
Examples of const member functions are functions which return by value
or by const reference/pointer (such as length(), size(), state() and
distance()) and non const member functions modify the visible state
(such as resize(), clear(), add() and remove()).

You should definitely read more about that, since const member functions
are a powerful feature for preventing silly programmers (as we all are)
from touching something they shouldn't touch (as we all do).
Jonathan


Jonathan thanks for the reasons for "const objects" reply above. Your reply
taught me a lot of things I couldn't quite grasp in the books I've read.

I have to admit though, I had to read over your reply five times before it sunk
in!

Thanks again.

Dennis

Jul 22 '05 #35

This discussion thread is closed

Replies have been disabled for this discussion.