473,486 Members | 2,243 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

Returning a pointer to a struct

Hey all,

I want to return a pointer to a struct. Here is what I'lm trying to do:

struct Position{
int x;
int y;
};

Position* GraphicTag::getRenderCentre(){
int cenx = m_renderPosition->x + m_size->width / 2;
int ceny = m_renderPosition->y + m_size->height / 2;

return (Position *){cenx,ceny}; // <---- Error here
}

I get "Error: initializer for scalar variable requires one element".
I'm a Java programmer at heart, and still a little uneasy around
pointers.

Thanks,
Matt

Nov 30 '06 #1
17 3215

dj*****@gmail.com schrieb:
I want to return a pointer to a struct. Here is what I'lm trying to do:

struct Position{
int x;
int y;
};

Position* GraphicTag::getRenderCentre(){
int cenx = m_renderPosition->x + m_size->width / 2;
int ceny = m_renderPosition->y + m_size->height / 2;

return (Position *){cenx,ceny}; // <---- Error here
}

I get "Error: initializer for scalar variable requires one element".
I'm a Java programmer at heart, and still a little uneasy around
pointers.
With a simple data structure like this, it does not make much sense to
use pointers at all. In C++, I would personally try to return a simple
structure like this by value or by reference first, and only as a last
resort would I use pointers.

You get the error since a pointer in C++ needs (or should) point to
something. In other words, you need to create a valid object to point
to first.

Your structure also has no applicable default constructor that could
help you here. You should consider adding one.

And finally, if you have this function create a "Position" object and
return a pointer to it, the caller will be responsible for deleting the
object - not necessarily a desired behaiour.

Alf P. Steinbach (frequent contributor in this group) has a good
tutorial on C++ pointers:
http://home.no.net/dubjai/win32cpptu...ters/ch_01.pdf

Cheers,
Andre

Nov 30 '06 #2
dj*****@gmail.com wrote:
I want to return a pointer to a struct. Here is what I'lm trying to
do:

struct Position{
int x;
int y;
};

Position* GraphicTag::getRenderCentre(){
int cenx = m_renderPosition->x + m_size->width / 2;
int ceny = m_renderPosition->y + m_size->height / 2;

return (Position *){cenx,ceny}; // <---- Error here
}

I get "Error: initializer for scalar variable requires one element".
I'm a Java programmer at heart, and still a little uneasy around
pointers.
Pointers are good when you have objects addresses of which you can
take and assign to those pointers. Your "{cenx,ceny}" syntax is not
C++. If you want to move along in C++, you'll need to un-learn some
of Java.

In this particular case do NOT return a pointer. Return an object:

Position GraphicTag::getRenderCentre(){
Position retval = { m_renderPosition->x + m_size->width/2,
m_renderPosition->x + m_size->height/2 };
return retval;
}

Of course, it's better to make your Position to have a c-tor that
would take two values and construct a temporary right in the
return expression.

struct Position{
int x;
int y;
Position(int xx, int yy) : x(xx), y(yy) {}
};

...
return Position( m_renderPosition..../2, m_render.../2 );
}

There are implications about adding your own c-tor to the struct,
so you decide which path to take.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Nov 30 '06 #3
Thank you both,

Firstly, what is the scope of a struct which is created (not as a
pointer) in a member function? I always thought it was local only
(would delete when the function is returned), but I'm clearly wrong
here. Does it last until the object that the member function belongs to
is destroyed?

Secondly, am I correct in thinking that there is no "inline" way of
creating a pointer to a struct like I was trying to, unless I define a
constructor? (I'm very stubborn, even if it isn't the right way, I like
to know where I was going wrong with the syntax).

Thanks again,
Matt

Nov 30 '06 #4

dj*****@gmail.com wrote:
Thank you both,

Firstly, what is the scope of a struct which is created (not as a
pointer) in a member function? I always thought it was local only
(would delete when the function is returned), but I'm clearly wrong
here. Does it last until the object that the member function belongs to
is destroyed?
The object created within the function has the scope of that function
and is indeed destroyed[*] at the end of that function. However, when
you return by value as Victor suggested, a whole new, entirely separate
object is created for the return value. So by the end of the function,
the local object has been destroyed, but that doesn't matter because
the return value is a different object that was created as a copy of
the local object while the local object still existed.
[*] Destroyed, not deleted. delete in C++ has a very specific meaning
(as a keyword, in all lower case). It is what you do to objects with
dynamic storage duration (those created with new) when you, the
programmer, decide it is time for them to cease existing.

Gavin Deane

Nov 30 '06 #5
dj*****@gmail.com wrote:
[..]
Secondly, am I correct in thinking that there is no "inline" way of
creating a pointer to a struct like I was trying to, unless I define a
constructor?
You can use syntax Position() for a default-initialised temporary, if
it can, the compiler declares and defines the default constructor for
you. In your case it doesn't make sense, of course.
(I'm very stubborn, even if it isn't the right way, I
like to know where I was going wrong with the syntax).
Well, the curly-brace enclosed initialiser list syntax is only used
(and available) in _declarations_, not in expressions. The 'return'
statement includes an expression. You can, as you know _declare_
(and define) your struct as

Position blah = { 1, 2 };

Here the "{ 1, 2 }" is the allowed initialiser syntax. You cannot
do, for example

foo( { 1, 2} );

(for some function 'foo' that takes 'Position' as its argument). It
is not allowed. If you need to create a temporary object and give it
some non-default value[s], the class has to define a c-tor, so you
can use the syntax

foo( Position(1,2) );

, for example.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Dec 1 '06 #6

dj*****@gmail.com wrote:
Thank you both,

Firstly, what is the scope of a struct which is created (not as a
pointer) in a member function? I always thought it was local only
(would delete when the function is returned), but I'm clearly wrong
here. Does it last until the object that the member function belongs to
is destroyed?
A struct doesn't have a scope - it doesn't exist. An instance of a
struct does.
The local variable dies with the function but if you return the
variable, a copy ctor creates a brand new object in main for you.
>
Secondly, am I correct in thinking that there is no "inline" way of
creating a pointer to a struct like I was trying to, unless I define a
constructor? (I'm very stubborn, even if it isn't the right way, I like
to know where I was going wrong with the syntax).

Thanks again,
Matt
Look at it this way. If you *could* use a pointer, you'ld be much
better off using a const reference instead. Pointers are responsible
for most of the bugs that programs suffer from. Even in the case of
allocations, pointers should be replaced by smart_ptr(s) and references
work nicely with polymorphism.
A C++ programmer'ss ultimate goal is (or should be) to write an entire
application without ever directly using a pointer. The resulting code
will be safer, bug-proof, easily maintainable and effortlessly
expandable/extendable.

The solution: a const reference. The only viable alternative is return
by copy. Are you ready? Cause there is a moral to the story...

#include <iostream>

class Position {
int x, y;
public:
Position() : x(0), y(0)
{
std::cout << "Position()\n";
}
Position(int x_, int y_) : x(x_), y(y_)
{
std::cout << "Position(int, int)\n";
}
Position(const Position& copy)
{
std::cout << "copy Position\n";
x = copy.x;
y = copy.y;
}
int getx() const { return x; }
int gety() const { return y; }
};

class Graphic
{
Position pos; // precious coordinate
public:
Graphic() : pos() { }
void move(const Position& r_pos)
{
pos = r_pos;
}
const Position& getpos() const // by const ref
{
return pos;
}
};

int main()
{
Graphic graphic;
graphic.move( Position(10,10) );
Position gpos = graphic.getpos();
std::cout << "pos.x = " << gpos.getx();
std::cout << "\npos.y = " << gpos.gety();
std::cout << std::endl;
}

/*
Position() // 0,0
Position(int, int) // 10,10
copy Position // the reference is copied safely
pos.x = 10
pos.y = 10
*/

Graphic's getpos() above is a viable candidate for a pointer return
since its returning an internal member. Thing is: why would i want a
user of the class to have *access* to my precious graphic's Position?
Even if it were to be accessed + modified by accident? You could return
a constant pointer - but then some smart-ass can const_cast<your
precious position into oblivion. I'm not joking - i'm dead serious.

Consider:

Position* const Graphic::getpos() // by constant pointer
{
return &pos;
}

some smart ass could write the following side-effect:

*graphic.getpos() = Position(-1,-1); // modifies your private member
!!!

and screw you royally. Try it. Even if getpos() is made const, i can
*still* modify the internal position with a Postion ptr and a
const_cast<>.

Forget doing that with a const reference. Its absolutely nuke-proof.

Dec 1 '06 #7
Salt_Peter <pj*****@yahoo.comwrote:
>A struct doesn't have a scope - it doesn't exist.
Sure it does. Try compiling the following.

void foo () {
{
struct goo {
int a;
};
goo b; // legal
}
goo c; // illegal, causes 'goo undeclared'
}

Steve
Dec 1 '06 #8

Steve Pope wrote:
Salt_Peter <pj*****@yahoo.comwrote:
A struct doesn't have a scope - it doesn't exist.

Sure it does. Try compiling the following.

void foo () {
{
struct goo {
int a;
};
goo b; // legal
dandy, but hardly the context at hand.
And lets not get confused with an instance's scope, type visibilty and
type accessibility.
What you have above is a struct in a closed anonymous namespace.

namespace GOO {
struct goo { };
}

void foo () {
GOO::goo b;
}

GOO::goo c;

int main()
{
GOO::goo d;
}

Dec 1 '06 #9
Salt_Peter <pj*****@yahoo.comwrote:
>Steve Pope wrote:
>Salt_Peter <pj*****@yahoo.comwrote:
>>A struct doesn't have a scope - it doesn't exist.
An instance of a struct does.
>Sure it does. Try compiling the following.
>void foo () {
{
struct goo {
int a;
};
goo b; // legal
>dandy, but hardly the context at hand.
And lets not get confused with an instance's scope, type visibilty and
type accessibility.
You're right that my point does not address the OP's concern, however
your statement above seemed to imply that you believe a structure
declaration (as opposed to the definition of an instance of the
structure) doesn't have scope. It does, and can be (among perhaps
other possibilities) either global to a file or local to a block.
>What you have above is a struct in a closed anonymous namespace.

namespace GOO {
struct goo { };
}

void foo () {
GOO::goo b;
}

GOO::goo c;

int main()
{
GOO::goo d;
}
I'm not sure I totally agree that names local to a block are
identical in behavior to names in an anonymous namespace. For one
thing, a name can be declared in an anonymous namespace and then used
outside the namespace's block but within the same file.

They are somewhat different scoping mechanisms.

Steve
Dec 1 '06 #10
On Dec 1, 12:09 am, djcr...@gmail.com wrote:
Hey all,

I want to return a pointer to a struct. Here is what I'lm trying to do:

struct Position{
int x;
int y;

};Position* GraphicTag::getRenderCentre(){
int cenx = m_renderPosition->x + m_size->width / 2;
int ceny = m_renderPosition->y + m_size->height / 2;

return (Position *){cenx,ceny}; // <---- Error here

}I get "Error: initializer for scalar variable requires one element".
I'm a Java programmer at heart, and still a little uneasy around
pointers.
I'd just like to add, if you haven't figured it out already, that in
principle there are two instances where you can return a pointer. The
first is if you have a class/struct with a member, then you can return
a pointer to that member, but as Salt_Peter has pointed out, this is
generally not a good idea. The second instance is when you dynamically
allocate memory for some type, in which case you get a pointer:

Position* GraphicTag::getRenderCentre(){
Position* pos = new Position; // OBS!
pos->x = m_renderPosition->x + m_size->width / 2;
pos->y = m_renderPosition->y + m_size->height / 2;

return pos;
}

As others have pointed out, this is generally a bad idea, the memory
allocated by new will not get freed until you call delete on a
Position-pointer that points to it (like the one returned from
getRenderCentre()), should you loose this pointer you have a
memory-leek. In general, every new shall have a delete, the problem is
that you only call new in one place but you often might need to delete
in several places. This leads to two problems, either you don't delete
where you should, and you get a memory-leek, or you try to use a
pointer that has already deleted, in which case (if you are lucky) the
program will crash (if you are unlucky anything could happen).

--
Erik Wikström

Dec 1 '06 #11
er****@student.chalmers.se <er****@student.chalmers.sewrote:
>I'd just like to add, if you haven't figured it out already, that in
principle there are two instances where you can return a pointer. The
first is if you have a class/struct with a member, then you can return
a pointer to that member, but as Salt_Peter has pointed out, this is
generally not a good idea. The second instance is when you dynamically
allocate memory for some type, in which case you get a pointer:
Actually, there's a third situation when you can return a pointer:
it can point to a static or global object. That's in a sense
the safest type of pointer to return.

Steve
Dec 1 '06 #12
Wow, this has been a very enlightening thread, thank you all who have
made time to post and write code examples!

Every new user should read this thread - many C++ books / tuts tell you
how to "code", but don't tell you how to "build software" if you know
what I mean. Rules like this should be committed to memory.

I have one final question if you would:

I have a class GraphicTag which has a member of type Tag (a class, not
struct). Both the Tag and GraphicTag objects are created in the main()
function, then the Tag is passed to the GraphicTag constructor:

int main(){

Tag tag(10,5);
GraphicTag gTag(// pass tag here to constructor);

}

My question is, how is it best to store the Tag inside the GraphicTag,
and hence, how is it best to pass it in the constructor? The Tag object
won't be changed inside the main() function; once it's passed to the
GraphicTag, it is left alone from the main() function's point of view.
Is it possible to do this:

int main(){
Tag* tag = new Tag(10,5);
GraphicTag gTag(tag);
}

class GraphicTag {
protected:
Tag m_tag;
};

GraphicTag::GraphicTag(Tag* tag){
m_tag = *tag; // m_tag is now the instance of the
created tag.
}

.... and is this even the best way?

Thanks again,
Matt

Dec 1 '06 #13
On Dec 1, 11:13 am, djcr...@gmail.com wrote:
Wow, this has been a very enlightening thread, thank you all who have
made time to post and write code examples!

Every new user should read this thread - many C++ books / tuts tell you
how to "code", but don't tell you how to "build software" if you know
what I mean. Rules like this should be committed to memory.

I have one final question if you would:

I have a class GraphicTag which has a member of type Tag (a class, not
struct). Both the Tag and GraphicTag objects are created in the main()
function, then the Tag is passed to the GraphicTag constructor:

int main(){

Tag tag(10,5);
GraphicTag gTag(// pass tag here to constructor);

}My question is, how is it best to store the Tag inside the GraphicTag,
and hence, how is it best to pass it in the constructor? The Tag object
won't be changed inside the main() function; once it's passed to the
GraphicTag, it is left alone from the main() function's point of view.
Is it possible to do this:

int main(){
Tag* tag = new Tag(10,5);
GraphicTag gTag(tag);

}class GraphicTag {
protected:
Tag m_tag;

};GraphicTag::GraphicTag(Tag* tag){
m_tag = *tag; // m_tag is now the instance of the
created tag.

}... and is this even the best way?
You could, but once again, a pointer is not the best way to do it.
There are two "problems" with this approach, first you use dynamic
allocated memory (new) when you don't have to, the second is that if
the tag created in main() won't change, you don't have to store a copy
of it in GraphicTag, you can store the thing itself (or rather a
reference to it).

class GraphicTag {
protected:
Tag& m_tag; // notice the &, a reference
};

GraphicTag::GraphicTag(Tag& tag){
m_tag = tag; // m_tag is now a reference to the tag
created in main
}

int main(){
Tag tag(10,5);
GraphicTag gTag(tag);
}

Read up on references, they can often be used where a pointer can be
used, and in those cases a reference is almost always preferable. A
note on style: try to keep at least the closing '}' on a separate line,
it will make the code easier to read.

--
Erik Wikström

Dec 1 '06 #14
On Dec 1, 11:39 am, "eri...@student.chalmers.se"
<eri...@student.chalmers.sewrote:
A
note on style: try to keep at least the closing '}' on a separate line,
it will make the code easier to read.
Disregard that, seems it's only google messing up the code.

--
Erik Wikström

Dec 1 '06 #15
Thank you, I am now much more clued-in about pointers and references. I
am very greatful! I will aim to use references much more now (I had
completely overlooked them and just jumped into pointers)!

Thanks again,
Matt

Dec 1 '06 #16

dj*****@gmail.com wrote:
I have a class GraphicTag which has a member of type Tag (a class, not
struct). Both the Tag and GraphicTag objects are created in the main()
function, then the Tag is passed to the GraphicTag constructor:

int main(){

Tag tag(10,5);
GraphicTag gTag(// pass tag here to constructor);

}

My question is, how is it best to store the Tag inside the GraphicTag,
and hence, how is it best to pass it in the constructor? The Tag object
won't be changed inside the main() function; once it's passed to the
GraphicTag, it is left alone from the main() function's point of view.
What do you mean by "it is left alone from the main() function's point
of view"? Do you mean main does not touch the Tag object, does not
change it, does not pass it to any other functions or objects, does not
care in any way about it after the GraphicTag is created? If so, then
the Tag is logically owned by the GraphicTag and should not even exist
in main.

class Tag
{
public:
Tag(int a, int b) {}
// ...
};

class GraphicTag
{
public:
GraphicTag(int tag_param_1, int tag_param_2) :
tag(tag_param_1, tag_param_2) {}
// ...
private:
Tag tag;
// ...
};

int main()
{
GraphicTag gTag(10, 5);
}

Gavin Deane

Dec 1 '06 #17

er****@student.chalmers.se wrote:
Read up on references, they can often be used where a pointer can be
used, and in those cases a reference is almost always preferable.
As long as that doesn't contradict the ownership semantics of the
design. I saw nothing in the original question to suggest that the
simplest solution, holding a member object rather than holding a
reference or pointer, was inappropriate.

Gavin Deane

Dec 1 '06 #18

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

Similar topics

11
2042
by: kelvSYC | last post by:
What is the best way to create functions that, based on some input, return either structures or a null value if the structure cannot be made? The problem is that the structure has be created...
4
4972
by: Anthony | last post by:
Hello, I am writing a function that populates an array of pointers to strings. Both the number of strings in the array, and the lengths of the strings, are dynamic; in particular, the number of...
6
2405
by: Generic Usenet Account | last post by:
Is it okay to return a local datastructure (something of type struct) from a function, as long as it does not have any pointer fields? I think it is a bad idea, but one of my colleagues does not...
3
2815
by: Michel Rouzic | last post by:
It's the first time I try using structs, and I'm getting confused with it and can't make it work properly I firstly define the structure by this : typedef struct { char *l1; int *l2; int Nval; }...
17
3215
by: I.M. !Knuth | last post by:
Hi. I'm more-or-less a C newbie. I thought I had pointers under control until I started goofing around with this: ...
6
1771
by: student1976 | last post by:
All Beginner/Intermediate level question. I understand that returning ptr to local stack vars is bad. Is returning foo_p_B from fnB() reliable all the time, so that using foo_p_A does not...
3
3645
by: John Turner | last post by:
typedef void (*vfp)(); typedef vfp (*fp)(); static fp hello() { printf("Hello.\n"); return (fp)&hello; } main(){
17
1666
by: daniel | last post by:
Hello , How safe is it to return a structure from a function. Let's say we have the following situation: typedef struct MyStruct{ int a;
5
2660
by: ctj951 | last post by:
I have a very specific question about a language issue that I was hoping to get an answer to. If you allocate a structure that contains an array as a local variable inside a function and return...
0
7099
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
6964
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
7123
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,...
0
7175
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...
1
6842
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...
1
4864
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...
0
4559
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...
0
3070
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
598
muto222
php
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.