Passing Stream object by reference

I

Ian Robertson

I am trying to write a function that takes a reference to an object as its
arguement. The object is created in another function and I am trying to pass
the object to another function from within the function that created the
object. I have cut out some code as I dont think showing a for loop is
helpful.

void TMP3_Main_Form::LoadMP3()
{
TMemoryStream *MP3Stream = new TMemoryStream();
MP3Stream->LoadFromFile(FileListBox1->Items->Strings.c_str());
GetMP3Data(&MP3Stream);
....
....
....
}

the object is created within this function. I load a file into the stream. I
then want to pass that stream to another function to perform other tasks on
the stream.

My GetMP3Data function accepts a pointer to a stream as its arguement.


void TMP3_Main_Form::GetMP3Data(TMemoryStream *MP3)
{
char DATA[3]={0,0,0};
MP3.Position = MP3.Seek(-128,soFromEnd);
MP3.Read(DATA,3);

/* Have tried
MP3->Position = MP3->Seek(-128,soFromEnd);
MP3->Read(DATA,3);
also but this didnt seem to work either
*/
....
....
....
}

I am having trouble with the * and & operators. I can use and process
MP3Stream within the LoadTag() function but not with the GetMP3Data
function. I am trying to avoid having to reload the file from disk from
scratch in the GetMP3Data function to get the data into the function.
Ideally I want to be able to load my file once into a stream in memory, do
my processing with a couple of different functions on the same stream, and
then rewrite the file back to disk from my updated stream. At the moment I
have to keep reloading the file from disk as I cant pass by reference
properly.

Can anyone help?

Thanks in advance
 
R

Rolf Magnus

Ian said:
I am trying to write a function that takes a reference to an object as
its arguement. The object is created in another function and I am
trying to pass the object to another function from within the function
that created the object. I have cut out some code as I dont think
showing a for loop is helpful.

void TMP3_Main_Form::LoadMP3()
{
TMemoryStream *MP3Stream = new TMemoryStream();
MP3Stream->LoadFromFile(FileListBox1->Items->Strings.c_str());
GetMP3Data(&MP3Stream);
...
...
...
}

the object is created within this function. I load a file into the
stream. I then want to pass that stream to another function to perform
other tasks on the stream.

My GetMP3Data function accepts a pointer to a stream as its arguement.


But above, a pointer to a pointer to a TMemoryStream is passed to
GetMP3Data. MP3Stream is a pointer to TMemoryStream, and &MP3Stream is
the address of that pointer. You want to pass the pointer itself, so
leave out the &.
void TMP3_Main_Form::GetMP3Data(TMemoryStream *MP3)
{
char DATA[3]={0,0,0};
MP3.Position = MP3.Seek(-128,soFromEnd);
MP3.Read(DATA,3);

/* Have tried
MP3->Position = MP3->Seek(-128,soFromEnd);
MP3->Read(DATA,3);
also but this didnt seem to work either
*/

The latter is correct. Are you sure you got the error _within_ that
function? Unfortunately, you forgot to post the error messages you got.
...
...
...
}

I am having trouble with the * and & operators. I can use and process
MP3Stream within the LoadTag() function but not with the GetMP3Data
function. I am trying to avoid having to reload the file from disk
from scratch in the GetMP3Data function to get the data into the
function. Ideally I want to be able to load my file once into a stream
in memory, do my processing with a couple of different functions on
the same stream, and then rewrite the file back to disk from my
updated stream. At the moment I have to keep reloading the file from
disk as I cant pass by reference properly.

Can anyone help?

I wonder where the reference is that you have been talking about at the
beginning. I only see pointers, no references.
 
J

John Harrison

Rolf Magnus said:
Ian said:
I am trying to write a function that takes a reference to an object as
its arguement. The object is created in another function and I am
trying to pass the object to another function from within the function
that created the object. I have cut out some code as I dont think
showing a for loop is helpful.

void TMP3_Main_Form::LoadMP3()
{
TMemoryStream *MP3Stream = new TMemoryStream();
MP3Stream->LoadFromFile(FileListBox1->Items->Strings.c_str());
GetMP3Data(&MP3Stream);
...
...
...
}

the object is created within this function. I load a file into the
stream. I then want to pass that stream to another function to perform
other tasks on the stream.

My GetMP3Data function accepts a pointer to a stream as its arguement.


But above, a pointer to a pointer to a TMemoryStream is passed to
GetMP3Data. MP3Stream is a pointer to TMemoryStream, and &MP3Stream is
the address of that pointer. You want to pass the pointer itself, so
leave out the &.


More likely is that the OP should not use new and instead leave in the &,
like this

void TMP3_Main_Form::LoadMP3()
{
TMemoryStream MP3Stream;
MP3Stream->LoadFromFile(FileListBox1->Items->Strings.c_str());
GetMP3Data(&MP3Stream);

Either way, if you use new you already have a pointer and so don't need &,
if you don't use new then you don't have a pointer and do need &.

The advantage of not using new is that you don't need to use delete and by
avoiding heap allocation it is likely to be more efficient.

john
 
J

John Harrison

void TMP3_Main_Form::LoadMP3()
{
TMemoryStream MP3Stream;
MP3Stream->LoadFromFile(FileListBox1->Items->Strings.c_str());


The above line should also change to

MP3Stream.LoadFromFile(FileListBox1->Items->Strings.c_str());
GetMP3Data(&MP3Stream);

Apologies.

john
 
R

Rolf Magnus

John said:
Rolf Magnus said:
Ian said:
I am trying to write a function that takes a reference to an object
as its arguement. The object is created in another function and I
am trying to pass the object to another function from within the
function that created the object. I have cut out some code as I
dont think showing a for loop is helpful.

void TMP3_Main_Form::LoadMP3()
{
TMemoryStream *MP3Stream = new TMemoryStream();
MP3Stream->LoadFromFile(FileListBox1->Items->Strings.c_str());
GetMP3Data(&MP3Stream);
...
...
...
}

the object is created within this function. I load a file into the
stream. I then want to pass that stream to another function to
perform other tasks on the stream.

My GetMP3Data function accepts a pointer to a stream as its
arguement.


But above, a pointer to a pointer to a TMemoryStream is passed to
GetMP3Data. MP3Stream is a pointer to TMemoryStream, and &MP3Stream
is the address of that pointer. You want to pass the pointer itself,
so leave out the &.


More likely is that the OP should not use new and instead leave in the
&, like this

void TMP3_Main_Form::LoadMP3()
{
TMemoryStream MP3Stream;
MP3Stream->LoadFromFile(FileListBox1->Items->Strings.c_str());
GetMP3Data(&MP3Stream);


I would have suggested that too, but I wasn't sure whether the OP wants
to use the stream after LoadMP3 (since he said he wanted to write to
the file later). But I guess you're right. After all, if he wanted to
use the stream later, it should have been a member variable, or at
least the function would have to return the pointer.
Either way, if you use new you already have a pointer and so don't
need &, if you don't use new then you don't have a pointer and do need
&.

Right. However, I'd suggest using a reference instead of a pointer as
parameter to GetMP3Data. Then, the & is again not needed.
 
D

Duane Hebert

Rolf Magnus said:
I would have suggested that too, but I wasn't sure whether the OP wants
to use the stream after LoadMP3 (since he said he wanted to write to
the file later). But I guess you're right. After all, if he wanted to
use the stream later, it should have been a member variable, or at
least the function would have to return the pointer.

TMemoryStream and TMemoryStream::LoadFromFile() look like
Borland VCL classes and functions. If so, the need to be created
on the heap and can't be instantiated without new. TMemoryStream
will fit nicely into an auto_ptr though.
 
I

Ian Robertson

Many thanks to John and Rolf. I am using borland cpp builder - which forces
the use of new with TMemoryStreams, and other VCL classes.
I have used your help to overcome my problem, and the performance gain over
having to reload the file from disk more than once is very noticable, since
my program goes through a batch of files at a time, only having to load a
file once makes a big difference when there are 30-100 files to process.


Rolf Magnus said:
John said:
Rolf Magnus said:
Ian Robertson wrote:

I am trying to write a function that takes a reference to an object
as its arguement. The object is created in another function and I
am trying to pass the object to another function from within the
function that created the object. I have cut out some code as I
dont think showing a for loop is helpful.

void TMP3_Main_Form::LoadMP3()
{
TMemoryStream *MP3Stream = new TMemoryStream();
MP3Stream->LoadFromFile(FileListBox1->Items->Strings.c_str());
GetMP3Data(&MP3Stream);
...
...
...
}

the object is created within this function. I load a file into the
stream. I then want to pass that stream to another function to
perform other tasks on the stream.

My GetMP3Data function accepts a pointer to a stream as its
arguement.

But above, a pointer to a pointer to a TMemoryStream is passed to
GetMP3Data. MP3Stream is a pointer to TMemoryStream, and &MP3Stream
is the address of that pointer. You want to pass the pointer itself,
so leave out the &.


More likely is that the OP should not use new and instead leave in the
&, like this

void TMP3_Main_Form::LoadMP3()
{
TMemoryStream MP3Stream;
MP3Stream->LoadFromFile(FileListBox1->Items->Strings.c_str());
GetMP3Data(&MP3Stream);


I would have suggested that too, but I wasn't sure whether the OP wants
to use the stream after LoadMP3 (since he said he wanted to write to
the file later). But I guess you're right. After all, if he wanted to
use the stream later, it should have been a member variable, or at
least the function would have to return the pointer.
Either way, if you use new you already have a pointer and so don't
need &, if you don't use new then you don't have a pointer and do need
&.

Right. However, I'd suggest using a reference instead of a pointer as
parameter to GetMP3Data. Then, the & is again not needed.
The advantage of not using new is that you don't need to use delete
and by avoiding heap allocation it is likely to be more efficient.
 

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
474,169
Messages
2,570,917
Members
47,458
Latest member
Chris#

Latest Threads

Top