function to return pointer question

A

Andrew Gentile

Hello,
I have been working on a program where I need to have a function
return an array. I found out that C doesn't do this, so now I am
trying to get the function to return a pointer to an array. It seems
easy, but I keep running into the same problem. The function appears
to execute properly, but when I print out the array values, only the
first one is correct. The other are all wrong. A snippet of code is
below. Please take a look and see what I have done wrong. Thank you
in advance for your help.

void main(void)
int *point(int); // function proto
int *p, i,count;
i=0;
count=5;

p=point(count); // call function, p should be value at array x2[0]

for(i=0;i<count;i++) // print out array

{
printf("\nfunction retun = %i",*p);
p++;
}
}


int *point(int k) // function to create array k-1 integers long.
{
int *p2,x2[k],i2;
i2=0;
while(i2<k)
{
x2[i2]=3*k;
i2++;
}
p2=x2;
return p2;
}
 
D

Default User

Andrew said:
Hello,
I have been working on a program where I need to have a function
return an array. I found out that C doesn't do this, so now I am
trying to get the function to return a pointer to an array. It seems
easy, but I keep running into the same problem. The function appears
to execute properly, but when I print out the array values, only the
first one is correct. The other are all wrong. A snippet of code is
below. Please take a look and see what I have done wrong. Thank you
in advance for your help.

In the future, please post EXACT code. Cut and paste. I can tell you
didn't because this is all screwed up and wouldn't have compiled.
void main(void)

main() returns int, ALWAYS. You're also missing then opening brace (and
the closing braces it would appear.
int *point(int); // function proto
int *p, i,count;
i=0;
count=5;

p=point(count); // call function, p should be value at array x2[0]

for(i=0;i<count;i++) // print out array

{
printf("\nfunction retun = %i",*p);
p++;
}
}


int *point(int k) // function to create array k-1 integers long.
{
int *p2,x2[k],i2;
i2=0;
while(i2<k)
{
x2[i2]=3*k;
i2++;
}
p2=x2;

You've set p2 to point to the start of an automatic array, which will
go out of scope as soon as the function returns. You can't do that.
return p2;
}

Either dynamically allocate the array in point() using malloc() or
friends, or pass in the array from the calling function.



Brian
 
R

Richard

Andrew Gentile said:
Hello,
I have been working on a program where I need to have a function
return an array. I found out that C doesn't do this, so now I am

The only type not strictly passed by value. A pointer to the array is
passed. Its a C thing.

With regards to your problem : Look at your local variable x2 in
function point(). A local will be effectively destroyed when you return
from the function which declared it.

Look into using malloc.

best of luck!
trying to get the function to return a pointer to an array. It seems
easy, but I keep running into the same problem. The function appears
to execute properly, but when I print out the array values, only the
first one is correct. The other are all wrong. A snippet of code is
below. Please take a look and see what I have done wrong. Thank you
in advance for your help.

void main(void)
int *point(int); // function proto
int *p, i,count;
i=0;
count=5;

p=point(count); // call function, p should be value at array x2[0]

for(i=0;i<count;i++) // print out array

{
printf("\nfunction retun = %i",*p);
p++;
}
}


int *point(int k) // function to create array k-1 integers long.
{
int *p2,x2[k],i2;
i2=0;
while(i2<k)
{
x2[i2]=3*k;
i2++;
}
p2=x2;
return p2;
}

--
 
R

Richard Heathfield

Richard said:
The only type not strictly passed by value.

Types aren't passed. Values are passed, and values have types. The value of
an array (that is, what you get when you use an array name in an expression
where it is not the operand of & or sizeof) is a pointer to its first
element.
A pointer to the array is passed.

No, a pointer to the array's first element is passed. This is the difference
between T * and T (*)[N].

And since the OP's program didn't even attempt to pass an array, I don't see
which point it is, precisely, that you are failing to make.
 
R

Richard

Richard Heathfield said:
Richard said:


Types aren't passed. Values are passed, and values have types. The
value of

Give me a break.

It makes perfect sense in the C context.

an array (that is, what you get when you use an array name in an expression
where it is not the operand of & or sizeof) is a pointer to its first
element.
A pointer to the array is passed.

No, a pointer to the array's first element is passed. This is the difference
between T * and T (*)[N].

Correct. Q : when is a pointer to an array NOT the same value as a
pointer to the first element of an arry?
And since the OP's program didn't even attempt to pass an array, I don't see
which point it is, precisely, that you are failing to make.

If you were to READ the OP then you would know to what I was referring.

You also snipped my reply to the actual PROBLEM he had.


--
 
K

Keith Thompson

Richard Heathfield said:
Richard said:

Types aren't passed. Values are passed, and values have types. The value of
an array (that is, what you get when you use an array name in an expression
where it is not the operand of & or sizeof) is a pointer to its first
element.
[...]

Your overall point is (unsurprisingly) correct, but I'm going to
quibble about the wording.

It's certainly true that "what you get when you use an array name in
an expression where it is not the operand of & or sizeof" is a pointer
to the array's first element. However, that's not what "the value of
an array" is. The value of an array ("array" here means "array
object") is the value of the array object itself, consisting of the
values of its elements.

When an array object's name is used as an expression (that is not the
operand of unary "&" or "sizeof"), the result of the expression is the
address of the array's first element; this is not the "value of the
array".

Incidentally while writing this I looked up the standard's definition
of "value" (C99 3.17):

precise meaning of the contents of an object when interpreted as
having a specific type

That would seem to imply that an expression such as 42, that doesn't
refer to any object, does not yield a "value". I've always thought of
a "value" as being either the interpreted contents of an object *or*
the result of an expression.

But the definition of "expression" (C99 6.5p1) is:

a sequence of operators and operands that specifies computation of
a value, or that designates an object or a function, or that
generates side effects, or that performs a combination thereof.

This isn't a big deal, just a bit of sloppy wording in the standard's
definitions.
 
R

Richard Heathfield

Richard said:
Give me a break.

First give me a switch.

It makes perfect sense in the C context.

No, it makes no sense at all in the C context.
an array (that is, what you get when you use an array name in an
expression where it is not the operand of & or sizeof) is a pointer to
its first element.
A pointer to the array is passed.

No, a pointer to the array's first element is passed. This is the
difference between T * and T (*)[N].

Correct. Q : when is a pointer to an array NOT the same value as a
pointer to the first element of an arry?

Always, because values have types, and a pointer to an array has a different
type to a pointer to the first element of that array.
If you were to READ the OP then you would know to what I was referring.

I did read the OP, and I still don't know to what your reply referred.
You also snipped my reply to the actual PROBLEM he had.

Yes, I did, and I don't think anything important was lost thereby.
 
R

Richard Heathfield

Keith Thompson said:
Richard Heathfield said:
Richard said:

Types aren't passed. Values are passed, and values have types. The value
of an array (that is, what you get when you use an array name in an
expression where it is not the operand of & or sizeof) is a pointer to
its first element.
[...]

Your overall point is (unsurprisingly) correct, but I'm going to
quibble about the wording.

Yes, I can understand why. Trying to get the wording precisely correct on
this matter can be a bit of a struggle, and I accept the quibble. My
parenthesised comment was meant to clarify the concept I was aiming at (the
- um - "entity" you get when you use an array name in an expression where
it is not an operand of sizeof or &), but I can see how it didn't achieve
that objective terribly well.

Incidentally while writing this I looked up the standard's definition
of "value" (C99 3.17):

precise meaning of the contents of an object when interpreted as
having a specific type

That would seem to imply that an expression such as 42, that doesn't
refer to any object, does not yield a "value". I've always thought of
a "value" as being either the interpreted contents of an object *or*
the result of an expression.

Yes, and both the C89 Standard and the C99 Standard refer to "the value of
CHAR_MIN" when describing numerical limits, even though it is quite evident
that CHAR_MIN is not an object. So, one way or another, the C99 Standard is
wrong.

<snip>
 
R

Richard Heathfield

Keith Thompson said:
Richard Heathfield said:
Richard said:

Types aren't passed. Values are passed, and values have types. The value
of an array (that is, what you get when you use an array name in an
expression where it is not the operand of & or sizeof) is a pointer to
its first element.
[...]

Your overall point is (unsurprisingly) correct, but I'm going to
quibble about the wording.

Yes, I can understand why. Trying to get the wording precisely correct on
this matter can be a bit of a struggle, and I accept the quibble. My
parenthesised comment was meant to clarify the concept I was aiming at (the
- um - "entity" you get when you use an array name in an expression where
it is not an operand of sizeof or &), but I can see how it didn't achieve
that objective terribly well.

Incidentally while writing this I looked up the standard's definition
of "value" (C99 3.17):

precise meaning of the contents of an object when interpreted as
having a specific type

That would seem to imply that an expression such as 42, that doesn't
refer to any object, does not yield a "value". I've always thought of
a "value" as being either the interpreted contents of an object *or*
the result of an expression.

Yes, and both the C89 Standard and the C99 Standard refer to "the value of
CHAR_MIN" when describing numerical limits, even though it is quite evident
that CHAR_MIN is not an object. So, one way or another, the C99 Standard is
wrong.

<snip>
 
B

Barry Schwarz

Hello,
I have been working on a program where I need to have a function
return an array. I found out that C doesn't do this, so now I am
trying to get the function to return a pointer to an array. It seems
easy, but I keep running into the same problem. The function appears
to execute properly, but when I print out the array values, only the
first one is correct. The other are all wrong. A snippet of code is
below. Please take a look and see what I have done wrong. Thank you
in advance for your help.

snip a very broken main
int *point(int k) // function to create array k-1 integers long.
{
int *p2,x2[k],i2;
i2=0;
while(i2<k)
{
x2[i2]=3*k;
i2++;
}
p2=x2;
return p2;
}

Your are returning the address of an automatic array that will go out
of existence as soon as you leave the function. Any attempt to use or
evaluate that address after point terminates invokes undefined
behavior. Three ways come to mind to prevent the array from
disappearing on you:

Declare it as static. Static objects are guaranteed to exist for
the duration of your program. This can cause problems if you call the
function twice and expect to be able to use both results
simultaneously.

Allocate it dynamically. Dynamic memory remains available until
you deliberately free it.

Define the array in the calling program and pass it to the called
function. The called function can update the array directly so
returning its address is a decision based on other design
considerations.


Remove del for email
 
A

Andrew Gentile

Thanks. I got it. The array is destroyed once the function is done
executing. This is why the first value of the array remains, because
it is stored with the pointer. So, if I declared my array as a global
variable, this would fix the problem. thanks again.

Andrew
Andrew Gentile said:
Hello,
I have been working on a program where I need to have a function
return an array. I found out that C doesn't do this, so now I am

The only type not strictly passed by value. A pointer to the array is
passed. Its a C thing.

With regards to your problem : Look at your local variable x2 in
function point(). A local will be effectively destroyed when you return
from the function which declared it.

Look into using malloc.

best of luck!
trying to get the function to return a pointer to an array. It seems
easy, but I keep running into the same problem. The function appears
to execute properly, but when I print out the array values, only the
first one is correct. The other are all wrong. A snippet of code is
below. Please take a look and see what I have done wrong. Thank you
in advance for your help.

void main(void)
int *point(int); // function proto
int *p, i,count;
i=0;
count=5;

p=point(count); // call function, p should be value at array x2[0]

for(i=0;i<count;i++) // print out array

{
printf("\nfunction retun = %i",*p);
p++;
}
}


int *point(int k) // function to create array k-1 integers long.
{
int *p2,x2[k],i2;
i2=0;
while(i2<k)
{
x2[i2]=3*k;
i2++;
}
p2=x2;
return p2;
}

--
 
R

Richard Heathfield

Andrew Gentile said:
Thanks. I got it. The array is destroyed once the function is done
executing. This is why the first value of the array remains, because
it is stored with the pointer.

No, it isn't. The pointer stores only a pointer value. In terms of the
abstract machine, the array is destroyed and the pointer value is
indeterminate. In practical terms, however, it is often the case that the
values you stored in the array may still be hanging around at the location
where it once existed. Nevertheless, a wise programmer will not rely on
this very unreliable behaviour, especially since those values could be
overwritten at any time.
So, if I declared my array as a global
variable, this would fix the problem.

It would, however, cause you other problems.

Either (a) create a large-enough array before calling the function, and pass
a pointer to its first element as an argument to the function, or (b)
dynamically allocate the array within the function and return a pointer to
its first element.
 
K

Keith Thompson

Richard Heathfield said:
Andrew Gentile said: [...]
So, if I declared my array as a global
variable, this would fix the problem.

It would, however, cause you other problems.

Either (a) create a large-enough array before calling the function, and pass
a pointer to its first element as an argument to the function, or (b)
dynamically allocate the array within the function and return a pointer to
its first element.

For (b), it becomes the caller's responsibility to free() the pointer to
the allocated memory.

Or (c) you can declare a *static* array within the function and return
a pointer to its first element; a static object does not cease to
exist when the function terminates. This solution has a number of
potential problems. The length is fixed; you'll probably either waste
space or not have enough. There's only one copy for all calls to the
function; if you call the function multiple times, each call can
clobber the result of the previous one. There are actually some
functions in the standard C library that use this approach; see
asctime(), for example.
 
A

Ark

Richard said:
Keith Thompson said:


Yes, and both the C89 Standard and the C99 Standard refer to "the value of
CHAR_MIN" when describing numerical limits, even though it is quite evident
that CHAR_MIN is not an object. So, one way or another, the C99 Standard is
wrong.

<snip>

Assuming e.g.
#define CHAR_MIN (-128)
isn't it true that CHAR_MIN is a const object of type int and value
-128? And likewise 42U a const object of type unsigned int and value 42?
Oh, it lacks an address but so do register variables.
Am I wrong? What's an object anyway then?
In any case, 42 and CHAR_MIN are expressions, so they have a type and a
value.
Am I wrong again?

Thanks,
-Ark
 
L

Lane Straatman

Richard Heathfield said:
Keith Thompson said:

Yes, I can understand why. Trying to get the wording precisely correct on
this matter can be a bit of a struggle, and I accept the quibble. My
parenthesised comment was meant to clarify the concept I was aiming at
(the
- um - "entity" you get when you use an array name in an expression where
it is not an operand of sizeof or &), but I can see how it didn't achieve
that objective terribly well.
Is the rub the nonsensical use of the word "object?"
Yes, and both the C89 Standard and the C99 Standard refer to "the value of
CHAR_MIN" when describing numerical limits, even though it is quite
evident
that CHAR_MIN is not an object. So, one way or another, the C99 Standard
is
wrong.
If one is not to use the word "object," what wording would you like to see?
LS
 
R

Richard Heathfield

Ark said:
Assuming e.g.
#define CHAR_MIN (-128)
isn't it true that CHAR_MIN is a const object of type int and value
-128?
No.

And likewise 42U a const object of type unsigned int and value 42?
No.

Oh, it lacks an address but so do register variables.

So do operators. That doesn't make them objects either.
Am I wrong?
Yes.

What's an object anyway then?

It is "a region of data storage in the execution environment, the contents
of which can represent values."
In any case, 42 and CHAR_MIN are expressions, so they have a type and a
value.

Yes, they are expressions, and they have a type and a value. But being an
expression is not enough to make you an object.
 
K

Keith Thompson

Ark said:
Assuming e.g.
#define CHAR_MIN (-128)
isn't it true that CHAR_MIN is a const object of type int and value
-128? And likewise 42U a const object of type unsigned int and value
42?

No. CHAR_MIN is merely a macro. It exists only in a C source file;
Objects exist at run time.

which needn't said:
Oh, it lacks an address but so do register variables.
Am I wrong? What's an object anyway then?

An object is a "region of data storage in the execution environment,
the contents of which can represent values" (C99 3.14).
In any case, 42 and CHAR_MIN are expressions, so they have a type and
a value.
Am I wrong again?

Yes, an expression has a type and a value. The only problem is that
the standard's definition of "value" isn't quite worded correctly.
 
S

Sjouke Burry

Ark said:
Assuming e.g.
#define CHAR_MIN (-128)
isn't it true that CHAR_MIN is a const object of type int and value
-128? And likewise 42U a const object of type unsigned int and value 42?
Oh, it lacks an address but so do register variables.
Am I wrong? What's an object anyway then?
In any case, 42 and CHAR_MIN are expressions, so they have a type and a
value.
Am I wrong again?
Yes , 42 is the answer to the reason for the universe :) :) ;)n
 
D

Dietmar Schindler

Richard said:
Keith Thompson said:


Yes, and both the C89 Standard and the C99 Standard refer to "the value of
CHAR_MIN" when describing numerical limits, even though it is quite evident
that CHAR_MIN is not an object. So, one way or another, the C99 Standard is
wrong.

From the definition of "value" being "precise meaning of the contents
of an object ...", it does not follow that in the phrase "the value of
CHAR_MIN" the noun "CHAR_MIN" were to be regarded as "an object".
We just have to keep in mind that "value" is defined as "precise meaning
....", and apply an appropriate one of the many meanings of "of" (found
at http://www.thefreedictionary.com/of for example); this way, "the
value of CHAR_MIN" can be restated as

"the precise meaning ... derived or coming from CHAR_MIN",

"the precise meaning ... associated with or adhering to CHAR_MIN",

"the precise meaning ... belonging or connected to CHAR_MIN",

"the precise meaning ... specified as, named or called CHAR_MIN";

also, "CHAR_MIN" can be an appositive noun, which is perhaps the best
way to see it.

crossposted to alt.usage.english
 
P

Peter Moylan

Dietmar said:
Richard said:
Keith Thompson said:
[...]
crossposted to alt.usage.english

The newsgroup alt.usage.english is, for the moment, occupied with a
discussion about the meaning of dates in C17 and C18, so it'll be a
while before we get as far as C99.

I feel your pain, but the C notation has always encouraged sloppiness
over the value/reference distinction, and things went totally out of
control when objects came into the picture. Given this, an error in the
standard is a mere bagatelle.

You might get AUE more interested in the question if you put it in the
context of what the name of the song is called.

--
Peter Moylan http://www.pmoylan.org

Please note the changed e-mail and web addresses. The domain
eepjm.newcastle.edu.au no longer exists, and I can no longer
receive mail at my newcastle.edu.au addresses. The optusnet
address could disappear at any time.
 

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,774
Messages
2,569,598
Members
45,144
Latest member
KetoBaseReviews
Top