473,842 Members | 1,963 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

how to return std::vector from function?

hi, c++ user

Suppose I constructed a large array and put it in the std::vector in a
function and now I want to return it back to where the function is called.
I can do like this:

std::vector<int > fun(){
//build the vector v;
return v;
}

int main(){
std::vector<int > a = fun();
return 0;
}

It works fine. However, I believe there is a deep copy in fun(), so the
cost is big when the array is big. Now I tried to return a pointer without
deep copy.

std::vector<int >* fun(){
//build a pointer to vector;
return *v;
}

int main(){
std::vector<int >* a = fun();
return 0;
}

This got memory leak trouble in fun() since v will be deleted after return
thus the pointer returned will be invalid.

Is there anyway that I can get a correct pointer from fun()? I also
thought to use a smart pointer, such as boost::shared_p tr:

boost::shared_p tr< std::vector<int > > getV(){
boost::shared_p tr< std::vector<int > > v;
v->push_back(1) ;
v->push_back(2) ;
return v;
}

int main(){
boost::shared_p tr< std::vector<int > > v = getV();
std::cout << v->at(0);
return 0;
}

I got the following message when run the program:
/usr/include/boost/shared_ptr.hpp: 253: T* boost::shared_p tr<T>::operator->() const [with T = std::vector<int , std::allocator< int> >]: Assertion `px != 0' failed.
Aborted

How can I get it correct? Is there any deep copy when the getV() return
the shared_ptr?

Thanks a lot.

zl2k
Mar 20 '06
32 69712
On Mon, 20 Mar 2006 21:08:29 +0100, loufoque
<lo******@remov e.gmail.com> wrote:
BigBrian a écrit :
That may be, but then if performance is an issue, you won't have to
assume that your compiler is smart enough to optimize.


If performance is an issue, use a performant compiler, that will indeed
optimize correctly.


What would you do with the returned temporary vector? Assign it to
another vector?

Regards,
Roland Pibinger
Mar 20 '06 #11

loufoque wrote:
BigBrian a écrit :
That may be, but then if performance is an issue, you won't have to
assume that your compiler is smart enough to optimize.


If performance is an issue, use a performant compiler, that will indeed
optimize correctly.

It's a waste of time trying the write fast code with a compiler that
doesn't translate C/C++ code into the most efficient machine code it could.


I disagree, especially in this case. Why return a huge object by value
and just hope the compiler does the optimization, when there are other
options that are just as easy to implement and then you *know* you
won't have this as a performance issue.

Also, using a different compiler isn't always an option.

-Brian

Mar 20 '06 #12
On Mon, 20 Mar 2006 09:55:01 -0800, BigBrian wrote:
std::vector<int >* fun(){
//build a pointer to vector;
return *v;
do you mean

return &v;

?
}

int main(){
std::vector<int >* a = fun();
return 0;
}

This got memory leak trouble in fun() since v will be deleted after return
thus the pointer returned will be invalid.


It's not a memory leak, you have a pointer to an object on the stack
that's not there anymore.
Is there anyway that I can get a correct pointer from fun()?


you could do something like this...

std::vector<int >* fun()
{
std::vector<int > * v = new std::vector<int >();
//build *v;
return v;
}

This has the same problem as mine: the v is lost after fun() is called and
the returned pointer is invalid.
and then make sure the caller deletes the returned value.
or you could do something like this...

void fun( std::vector<int > & v )
{
// build v;
}
}
int main()
{
std::vector<int > x;
fun(x);
}
}
-Brian

This works but for some reason I can't transfer an empty vector to the fun
and before the fun is called.
Mar 20 '06 #13
On Mon, 20 Mar 2006 14:48:55 -0500, Clark S. Cox III wrote:
On 2006-03-20 12:35:39 -0500, zl2k <kd*******@gmai l.com> said:
Is there anyway that I can get a correct pointer from fun()? I also
thought to use a smart pointer, such as boost::shared_p tr:

boost::shared_p tr< std::vector<int > > getV(){
boost::shared_p tr< std::vector<int > > v;
v->push_back(1) ;
v->push_back(2) ;
return v;
}

int main(){
boost::shared_p tr< std::vector<int > > v = getV();
std::cout << v->at(0);
return 0;
}

I got the following message when run the program:
/usr/include/boost/shared_ptr.hpp: 253: T*
boost::shared_p tr<T>::operator->() const [with T = std::vector<int ,
std::allocator< int> >]: Assertion `px != 0' failed.
Aborted


Your code is essentially right, save for one thing: You never set the
pointer to point at anything; i.e. it is a default constructed NULL
shared_ptr. Try this instead:

boost::shared_p tr< std::vector<int > > getV(){
//Note the 'new' on the next line, as it is what actually creates the vector
boost::shared_p tr< std::vector<int > > v = new std::vector<int >;
v->push_back(1) ;
v->push_back(2) ;
return v;
}

int main(){
boost::shared_p tr< std::vector<int > > v = getV();
std::cout << v->at(0);
return 0;
}


It looks good, but can I sure that there is no deep copy involved when
getV() is called?

Mar 20 '06 #14
On Mon, 20 Mar 2006 20:33:00 +0100, Matthias Kluwe wrote:
Hi!

zl2k <kd*******@gmai l.com>:
[...]

In some cases, I can't construct an empty container and pass it to the
function. I want the class which owns the member function fun to own the
container. Say,

Class A {
public:
void GenerateBigData ();
void getBigData();
private:
std::vector<int > bigData;
}

Basically, the bigData is generated within the class A. When I need it, I
just want to access the bigData by calling getBigData. I don't want a
duplicated copy of the bigData, a reference will be good. I don't know how
to implement it.


If you find a reference acceptable, why not let getBigData return a const reference to bigData?

Regards,
Matthias


how to do that?
Mar 20 '06 #15
On Mon, 20 Mar 2006 12:32:48 -0800, BigBrian wrote:

loufoque wrote:
BigBrian a écrit :
> That may be, but then if performance is an issue, you won't have to
> assume that your compiler is smart enough to optimize.


If performance is an issue, use a performant compiler, that will indeed
optimize correctly.

It's a waste of time trying the write fast code with a compiler that
doesn't translate C/C++ code into the most efficient machine code it could.


I disagree, especially in this case. Why return a huge object by value
and just hope the compiler does the optimization, when there are other
options that are just as easy to implement and then you *know* you
won't have this as a performance issue.

Also, using a different compiler isn't always an option.

-Brian


So what is the straight forward way to solve the problem (without passing
an empty container into the fun and porpulize it inside)?
Mar 20 '06 #16
zl2k <kd*******@gmai l.com> wrote:
On Mon, 20 Mar 2006 09:55:01 -0800, BigBrian wrote:
you could do something like this...

std::vector<int >* fun()
{
std::vector<int > * v = new std::vector<int >();
//build *v;
return v;
}


This has the same problem as mine: the v is lost after fun() is called and
the returned pointer is invalid.


Not quite. The v is lost after fun() is called, but the memory
pointed-to by v is still there and valid since it was allocated
dynamically on the heap, as opposed to on the stack. Then, returning a
pointer to this memory is OK, since it will exist longer than the
lifetime of fun().

--
Marcus Kwok
Mar 20 '06 #17
Marcus Kwok <ri******@gehen nom.net.invalid > wrote:
zl2k <kd*******@gmai l.com> wrote:
On Mon, 20 Mar 2006 09:55:01 -0800, BigBrian wrote:
you could do something like this...

std::vector<int >* fun()
{
std::vector<int > * v = new std::vector<int >();
//build *v;
return v;
}


This has the same problem as mine: the v is lost after fun() is called and
the returned pointer is invalid.


Not quite. The v is lost after fun() is called, but the memory
pointed-to by v is still there and valid since it was allocated
dynamically on the heap, as opposed to on the stack. Then, returning a
pointer to this memory is OK, since it will exist longer than the
lifetime of fun().


I should add that the caller of fun() is now responsible for deleting
the vector too.

--
Marcus Kwok
Mar 20 '06 #18
In article <pa************ *************** *@gmail.com>,
zl2k <kd*******@gmai l.com> wrote:
Class A {
public:
void GenerateBigData ();
void getBigData();
private:
std::vector<int > bigData;
}

Basically, the bigData is generated within the class A. When I need it, I
just want to access the bigData by calling getBigData. I don't want a
duplicated copy of the bigData, a reference will be good. I don't know how
to implement it.


Assuming that your code *really* can't make a copy of bigData then:

(best solution) Move the code that needs bigData into class A.

(next best) Have class A provide a const iterator to the beginning and
end of bigData.

class A {
vector<int> bigData;
void generateBigData (); // called from A's c_tor
public:
typedef vector<int>::co nst_iterator const_iterator;

A(): bigData() { generateBigData (); }

const_iterator begin() const { return bigData.begin() ; }
const_iterator end() const { return bigData.end(); }
};

(next best) return a const reference to bigData.

class A {
vector< int > bigData;
public:
typedef vector< int > BigDataType;

const BigDataType& getBigData() const { return bigData; }
};

--
Magic depends on tradition and belief. It does not welcome observation,
nor does it profit by experiment. On the other hand, science is based
on experience; it is open to correction by observation and experiment.
Mar 20 '06 #19
Roland Pibinger a écrit :
What would you do with the returned temporary vector? Assign it to
another vector?


#include <iostream>

class Foo
{
public:
Foo()
{
std::cout << "Constructo r of " << this << std::endl;
}

Foo(const Foo &foo)
{
std::cout << "Copying " << &foo << " to " << this << std::endl;
}

~Foo()
{
std::cout << "Destructor of " << this << std::endl;
}
};

Foo bar()
{
Foo foo;
/* whatever */
return foo;
}

int main()
{
Foo foo = bar();
}

If you compile this with gcc in normal mode, you can see there is no
copying done. (you can disable those optimizations in gcc with
-fno-elide-constructors, and you will therefore see that it is copied twice)
Other modern compilers probably do so too.

I know old compilers like MSVC6 only partially optimize that, copying it
once.

Mar 21 '06 #20

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

18
2891
by: Janina Kramer | last post by:
hi ng, i'm working on a multiplayer game for a variable number of players and on the client side, i'm using a std::vector<CPlayer> to store informatik about the players. CPlayer is a class that contains another std::vector<CPosition>. Because one of the players is the client itself (and the size of the vector<CPlayer> doesn't change during a game), i thought i could store a std::vector<CPlayer>::iterator "localplayer" that points to the...
17
3368
by: Michael Hopkins | last post by:
Hi all I want to create a std::vector that goes from 1 to n instead of 0 to n-1. The only change this will have is in loops and when the vector returns positions of elements etc. I am calling this uovec at the moment (for Unit-Offset VECtor). I want the class to respond correctly to all usage of STL containers and algorithms so that it is a transparent replacement for std:vector. The options seems to be:
0
10942
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10610
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
10671
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
10310
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
9452
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
7855
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
7035
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5884
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
2
4088
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.