How to reuse a deleted pointer?

D

Damon

Hi,

Can someone point out to me what's wrong with the code below? I'm
trying to reuse the deleted pointer but it won't compile. My reason
may be wrong, but I thought reusing the pointer would save the trouble
of declaring a pointer to a string array.

I also suspect there will be a problem of releasing memory in the way
I'm using the array pointer and is toying with using a
vector<std::string> instead. Anyway, thanks for any pointers give.

--------------snip---------------------
std::map<int, std::string*> notes;
std::string *bi_val = new std::string[2];
bi_val[0] = "W";
bi_val[1] = "E";
notes.insert( std::pair<int,std::string*>( 4, bi_val ) );
bi_val = new std:string[2]; // error here
bi_val[0] = "S";
bi_val[1] = "N";
notes.insert( std::pair<int,std::string*>( 2, bi_val ) );
bi_val = new std:string[2]; // same error here
bi_val[0] = "SE";
bi_val[1] = "NW";
notes.insert( std::pair<int,std::string*>( -2, bi_val ) );
bi_val = new std:string[2]; // error!
bi_val[0] = "SW";
bi_val[1] = "NE";
notes.insert( std::pair<int,std::string*>( 6, bi_val ) );
 
S

Simon Saunders

Hi,

Can someone point out to me what's wrong with the code below? I'm trying
to reuse the deleted pointer but it won't compile. My reason may be
wrong, but I thought reusing the pointer would save the trouble of
declaring a pointer to a string array.

I also suspect there will be a problem of releasing memory in the way
I'm using the array pointer and is toying with using a
vector<std::string> instead. Anyway, thanks for any pointers give.

--------------snip---------------------
std::map<int, std::string*> notes;
std::string *bi_val = new std::string[2]; bi_val[0] = "W";
bi_val[1] = "E";
notes.insert( std::pair<int,std::string*>( 4, bi_val ) ); bi_val =
new std:string[2]; // error here

You've missed out a colon, i.e. the line above should be

bi_val = new std::string[2];

By the way, if the number of array elements is always two you could
replace the array or vector with std::pair<std::string, std::string>.
Otherwise I would go with std::vector.
 
L

Leor Zolman

Hi,

Can someone point out to me what's wrong with the code below? I'm
trying to reuse the deleted pointer but it won't compile. My reason
may be wrong, but I thought reusing the pointer would save the trouble
of declaring a pointer to a string array.

I also suspect there will be a problem of releasing memory in the way
I'm using the array pointer and is toying with using a
vector<std::string> instead. Anyway, thanks for any pointers give.

--------------snip---------------------
std::map<int, std::string*> notes;
std::string *bi_val = new std::string[2];
bi_val[0] = "W";
bi_val[1] = "E";
notes.insert( std::pair<int,std::string*>( 4, bi_val ) );
bi_val = new std:string[2]; // error here
bi_val[0] = "S";
bi_val[1] = "N";
notes.insert( std::pair<int,std::string*>( 2, bi_val ) );
bi_val = new std:string[2]; // same error here
bi_val[0] = "SE";
bi_val[1] = "NW";
notes.insert( std::pair<int,std::string*>( -2, bi_val ) );
bi_val = new std:string[2]; // error!
bi_val[0] = "SW";
bi_val[1] = "NE";
notes.insert( std::pair<int,std::string*>( 6, bi_val ) );

The _syntax_ error is that you're using : instead of :: ...

The _logical_ error is that you're not deleting the pointer _between
uses_, so each time you "new" before you've deleted the previous
value, you're leaking a bit more memory that cannot be recovered
during the program's run...
-leor

Leor Zolman
BD Software
(e-mail address removed)
www.bdsoft.com -- On-Site Training in C/C++, Java, Perl & Unix
C++ users: Download BD Software's free STL Error Message
Decryptor at www.bdsoft.com/tools/stlfilt.html
 
C

Chris \( Val \)

| On Sat, 24 Jan 2004 04:37:37 -0800, Damon wrote:
|
| > Hi,
| >
| > Can someone point out to me what's wrong with the code below? I'm trying
| > to reuse the deleted pointer but it won't compile. My reason may be
| > wrong, but I thought reusing the pointer would save the trouble of
| > declaring a pointer to a string array.
| >
| > I also suspect there will be a problem of releasing memory in the way
| > I'm using the array pointer and is toying with using a
| > vector<std::string> instead. Anyway, thanks for any pointers give.
| >
| > --------------snip---------------------
| > std::map<int, std::string*> notes;
| > std::string *bi_val = new std::string[2]; bi_val[0] = "W";
| > bi_val[1] = "E";
| > notes.insert( std::pair<int,std::string*>( 4, bi_val ) ); bi_val =
| > new std:string[2]; // error here
|
| You've missed out a colon, i.e. the line above should be
|
| bi_val = new std::string[2];

Additionally, there is a memory leak due to the fact that
the OP is not using 'delete[]', prior to re-allocating
recourses.

Cheers.
Chris Val
 
S

Simon Saunders

Hi,

Can someone point out to me what's wrong with the code below? I'm trying
to reuse the deleted pointer but it won't compile. My reason may be
wrong, but I thought reusing the pointer would save the trouble of
declaring a pointer to a string array.

I also suspect there will be a problem of releasing memory in the way
I'm using the array pointer and is toying with using a
vector<std::string> instead. Anyway, thanks for any pointers give.

--------------snip---------------------
std::map<int, std::string*> notes;
std::string *bi_val = new std::string[2]; bi_val[0] = "W"; bi_val[1]
= "E";
notes.insert( std::pair<int,std::string*>( 4, bi_val ) ); bi_val =
new std:string[2]; // error here bi_val[0] = "S"; bi_val[1] = "N";
notes.insert( std::pair<int,std::string*>( 2, bi_val ) ); bi_val =
new std:string[2]; // same error here bi_val[0] = "SE"; bi_val[1] =
"NW";
notes.insert( std::pair<int,std::string*>( -2, bi_val ) ); bi_val =
new std:string[2]; // error! bi_val[0] = "SW"; bi_val[1] = "NE";
notes.insert( std::pair<int,std::string*>( 6, bi_val ) );

The _syntax_ error is that you're using : instead of :: ...

The _logical_ error is that you're not deleting the pointer _between
uses_, so each time you "new" before you've deleted the previous value,
you're leaking a bit more memory that cannot be recovered during the
program's run...
-leor

No. The pointers are stored in a map so it would be incorrect to delete
each one immediately after inserting it (the map would contain junk). Of
course, in order to prevent memory leaks it is necessary to delete each of
the stored arrays when the map is no longer needed.
 
S

Simon Saunders

| On Sat, 24 Jan 2004 04:37:37 -0800, Damon wrote:
|
| > Hi,
| >
| > Can someone point out to me what's wrong with the code below? I'm trying
| > to reuse the deleted pointer but it won't compile. My reason may be
| > wrong, but I thought reusing the pointer would save the trouble of
| > declaring a pointer to a string array.
| >
| > I also suspect there will be a problem of releasing memory in the way
| > I'm using the array pointer and is toying with using a
| > vector<std::string> instead. Anyway, thanks for any pointers give.
| >
| > --------------snip---------------------
| > std::map<int, std::string*> notes;
| > std::string *bi_val = new std::string[2]; bi_val[0] = "W";
| > bi_val[1] = "E";
| > notes.insert( std::pair<int,std::string*>( 4, bi_val ) ); bi_val =
| > new std:string[2]; // error here
|
| You've missed out a colon, i.e. the line above should be
|
| bi_val = new std::string[2];

Additionally, there is a memory leak due to the fact that
the OP is not using 'delete[]', prior to re-allocating
recourses.

If by that you mean there should be a line "delete[] bi_val" after each
line that begins "notes.insert(..." you are wrong, because you would end
up with a map containing junk pointers. Obviously those pointers must be
deleted at some point before the map goes out of scope to avoid memory
leakage.
 
C

Chris \( Val \)

| On Sun, 25 Jan 2004 00:13:34 +1100, Chris ( Val ) wrote:
|
| >
| > | > | On Sat, 24 Jan 2004 04:37:37 -0800, Damon wrote:
| > |
| > | > Hi,
| > | >
| > | > Can someone point out to me what's wrong with the code below? I'm trying
| > | > to reuse the deleted pointer but it won't compile. My reason may be
| > | > wrong, but I thought reusing the pointer would save the trouble of
| > | > declaring a pointer to a string array.
| > | >
| > | > I also suspect there will be a problem of releasing memory in the way
| > | > I'm using the array pointer and is toying with using a
| > | > vector<std::string> instead. Anyway, thanks for any pointers give.
| > | >
| > | > --------------snip---------------------
| > | > std::map<int, std::string*> notes;
| > | > std::string *bi_val = new std::string[2]; bi_val[0] = "W";
| > | > bi_val[1] = "E";
| > | > notes.insert( std::pair<int,std::string*>( 4, bi_val ) ); bi_val =
| > | > new std:string[2]; // error here
| > |
| > | You've missed out a colon, i.e. the line above should be
| > |
| > | bi_val = new std::string[2];
| >
| > Additionally, there is a memory leak due to the fact that
| > the OP is not using 'delete[]', prior to re-allocating
| > recourses.
| >
|
| If by that you mean there should be a line "delete[] bi_val" after each
| line that begins "notes.insert(..." you are wrong, because you would end
| up with a map containing junk pointers. Obviously those pointers must be
| deleted at some point before the map goes out of scope to avoid memory
| leakage.

Oop's, you're right.

I didn't realise the container wasn't making a copy here.

Thanks.
Chris Val
 
D

David Harmon

bi_val = new std:string[2]; // error here

No fair asking about an error without quoting the error message.
As others have noted, missing ":".
std::map<int, std::string*> notes;
std::string *bi_val = new std::string[2];
bi_val[0] = "W";
bi_val[1] = "E";
notes.insert( std::pair<int,std::string*>( 4, bi_val ) );

Pardon me for saying, isn't this some rather complicated code to do
a simple thing? (Which would be my worry any time I see "new" in
application level code.) What are you trying to accomplish, and
wouldn't it be easier with a const data table built at compile time?
Thereby avoiding all the memory leak issues?
 
C

Cy Edmunds

Damon said:
Hi,

Can someone point out to me what's wrong with the code below? I'm
trying to reuse the deleted pointer but it won't compile. My reason
may be wrong, but I thought reusing the pointer would save the trouble
of declaring a pointer to a string array.

I also suspect there will be a problem of releasing memory in the way
I'm using the array pointer and is toying with using a
vector<std::string> instead. Anyway, thanks for any pointers give.

--------------snip---------------------
std::map<int, std::string*> notes;
std::string *bi_val = new std::string[2];
bi_val[0] = "W";
bi_val[1] = "E";
notes.insert( std::pair<int,std::string*>( 4, bi_val ) );
bi_val = new std:string[2]; // error here
bi_val[0] = "S";
bi_val[1] = "N";
notes.insert( std::pair<int,std::string*>( 2, bi_val ) );
bi_val = new std:string[2]; // same error here
bi_val[0] = "SE";
bi_val[1] = "NW";
notes.insert( std::pair<int,std::string*>( -2, bi_val ) );
bi_val = new std:string[2]; // error!
bi_val[0] = "SW";
bi_val[1] = "NE";
notes.insert( std::pair<int,std::string*>( 6, bi_val ) );

Your design is very awkward. C arrays and unnecessary use of operator new
are both to be avoided if possible. Here it is not only possible, it's easy:

class ds // direction strings
{
private:
std::string m_dir;
std::string m_opp;
public:
ds() {}
ds(const std::string &i_dir, const std::string &i_opp) :
m_dir(i_dir), m_opp(i_opp) {}
const std::string &dir() const {return m_dir;}
const std::string &opp() const {return m_opp;}
};

std::map<int, ds> notes;
notes[4] = ds("W", "E");
notes[2] = ds("S", "N");
notes[-2] = ds("SE", "NW");
notes[6] = ds("SW", "NE");
 
J

Jeff Schwab

Damon said:
Hi,

Can someone point out to me what's wrong with the code below? I'm
trying to reuse the deleted pointer but it won't compile. My reason
may be wrong, but I thought reusing the pointer would save the trouble
of declaring a pointer to a string array.

I also suspect there will be a problem of releasing memory in the way
I'm using the array pointer and is toying with using a
vector<std::string> instead. Anyway, thanks for any pointers give.

--------------snip---------------------
std::map<int, std::string*> notes;
std::string *bi_val = new std::string[2];
bi_val[0] = "W";
bi_val[1] = "E";
notes.insert( std::pair<int,std::string*>( 4, bi_val ) );
bi_val = new std:string[2]; // error here
bi_val[0] = "S";
bi_val[1] = "N";
notes.insert( std::pair<int,std::string*>( 2, bi_val ) );
bi_val = new std:string[2]; // same error here
bi_val[0] = "SE";
bi_val[1] = "NW";
notes.insert( std::pair<int,std::string*>( -2, bi_val ) );
bi_val = new std:string[2]; // error!
bi_val[0] = "SW";
bi_val[1] = "NE";
notes.insert( std::pair<int,std::string*>( 6, bi_val ) );

What others said. I especially like Cy's solution. This might give
better performance, though.

#include <utility>

typedef char const* String_pair[ 2 ];

struct Note_map
{
String_pair const& operator [ ] ( int ) const;
private:
static String_pair const m_string_pairs[ ];
};

String_pair const Note_map::m_string_pairs[ ] =
{
{ "SE", "NW" }, // -2
{ 0, 0 },
{ 0, 0 }, // 0
{ 0, 0 },
{ "S", "N" }, // 2
{ 0, 0 },
{ "W", "E" }, // 4
{ 0, 0 },
{ "SW", "NE" } // 6
};

#include <iostream>

int main( )
{
Note_map notes;

std::cout << notes[ 4 ][ 0 ] << '\n'
<< notes[ 2 ][ 0 ] << '\n'
<< notes[ -2 ][ 0 ] << '\n'
<< notes[ 6 ][ 0 ] << '\n';
}

String_pair const& Note_map::eek:perator [ ] ( int i ) const
{
return m_string_pairs[ i + 2 ];
}
 
L

Leor Zolman

|
| If by that you mean there should be a line "delete[] bi_val" after each
| line that begins "notes.insert(..." you are wrong, because you would end
| up with a map containing junk pointers. Obviously those pointers must be
| deleted at some point before the map goes out of scope to avoid memory
| leakage.

Oop's, you're right.

I didn't realise the container wasn't making a copy here.

I didn't either! Simon caught us _both_ sleeping ;-)
-leor
Thanks.
Chris Val

Leor Zolman
BD Software
(e-mail address removed)
www.bdsoft.com -- On-Site Training in C/C++, Java, Perl & Unix
C++ users: Download BD Software's free STL Error Message
Decryptor at www.bdsoft.com/tools/stlfilt.html
 
F

Frank Puck

Damon said:
std::map<int, std::string*> notes;
std::string *bi_val = new std::string[2];
bi_val[0] = "W";
bi_val[1] = "E";
notes.insert( std::pair<int,std::string*>( 4, bi_val ) );
bi_val = new std:string[2]; // error here
bi_val[0] = "S";
bi_val[1] = "N";
notes.insert( std::pair<int,std::string*>( 2, bi_val ) );
bi_val = new std:string[2]; // same error here
bi_val[0] = "SE";
bi_val[1] = "NW";
notes.insert( std::pair<int,std::string*>( -2, bi_val ) );
bi_val = new std:string[2]; // error!
bi_val[0] = "SW";
bi_val[1] = "NE";
notes.insert( std::pair<int,std::string*>( 6, bi_val ) );

why don't you use

std::map<int, std::pair<std::string, std::string> > notes;

and you would avoid all the memory leaks...
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,773
Messages
2,569,594
Members
45,119
Latest member
IrmaNorcro
Top