423,680 Members | 2,439 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 423,680 IT Pros & Developers. It's quick & easy.

How to pass a pointer to an unknown-size array?

P: n/a

Hello!

I can pass a "pointer to a double" to a function that accepts
double*, like this:

int func(double* var) {
*var=1.0;
...
}

double var;

n=func(&var);

---

Now I want to pass a pointer to an array of doubles, the size
of the array must not be fixed though:

int func(double[]* array) {
int index;
index=3;
array[index]=1.0;
...
}

double array[100];

n=func(&array);

with the above code the compiler gives me an error. The only
solution that I found so far is this very inelegant one:

int func(void* array) {
int index;
index=3;
*((double*)(array)+index)=1.0;
...
}

double array[100];

n=func(&array);

---

There must be a cleaner way.. but what is it?

I am interested in both C and "C++ only" solutions.

Thanks!
Mike

Nov 14 '05 #1
Share this Question
Share on Google+
10 Replies


P: n/a
no****@nospam.com wrote:
Now I want to pass a pointer to an array of doubles, the size
of the array must not be fixed though:

int func(double[]* array) {
int index;
index=3;
array[index]=1.0;
...
}

double array[100];

n=func(&array);


The standard way of doing it is like this:

int func(double* array){
array[3]=1.0;
...
}

double array[100];

n=func(array);

The last line is equivalent to this:

n=func(&array[0]);

The reason is that the name of an array is a synonym for the location of
the initial element.

Espen
--
Numbers are the free creation of the human mind.
Julius Wilhelm Richard Dedekind
Nov 14 '05 #2

P: n/a
> Now I want to pass a pointer to an array of doubles, the size
of the array must not be fixed though:


Try this:

int func(double *array, int num_elements)
{
int i;
for(i = 0; i < num_elements; i++)
{
array[i] = 1.0;
}
}

int main()
{
double array[100];
func(array, 100);
}

The single pointer will point to the first element of the array. You do
not need double indirection. You need to explicitly pass the size of
the array, as C does not keep that information store.

Jon
----
Learn to program using Linux assembly language
http://www.cafeshops.com/bartlettpublish.8640017
Nov 14 '05 #3

P: n/a


no****@nospam.com wrote:
Hello!

I can pass a "pointer to a double" to a function that accepts
double*, like this:

int func(double* var) {
*var=1.0;
...
}

double var;

n=func(&var);

---

Now I want to pass a pointer to an array of doubles, the size
of the array must not be fixed though:

int func(double[]* array) {
int index;
index=3;
array[index]=1.0;
...
}

double array[100];

n=func(&array);

with the above code the compiler gives me an error. The only
solution that I found so far is this very inelegant one:

int func(void* array) {
int index;
index=3;
*((double*)(array)+index)=1.0;
...
}

double array[100];

n=func(&array);

---

There must be a cleaner way.. but what is it?

I am interested in both C and "C++ only" solutions.

Thanks!
Mike


int func(double *array, size_t arrsize)
{
int index = 3;
if (index < arrsize)
{
array[index]=1.0;
}
...
}

....

double array[100];
int n = func(array, sizeof array);
....

Remember that in C, the subscripting operation a[i] is *defined* as
*(a+i). Therefore, in *most* expression contexts (sizeof() being one
of two exceptions IINM), the type of a is converted from array of T to
pointer to T, and its value is set to the address of the first element
in the array (&a[0]), so the expression *(a+i) yields the correct
result. Because of this conversion, when you pass an array as a
parameter to a function, what you wind up passing is a pointer to the
base type, and its value is the address of the first element (this is
why I didn't use the address operator & in the function call above).

If you need to know the size of the array in the function, you need to
specify the array size as a separate parameter; a pointer doesn't know
the size of the chunk of memory it's pointing to.

If you wished to pass a pointer to the array object (not just a pointer
to the first element), the code would look like this:

int func(double (*array)[100]) // size must match original
{
int index=3;
(*array)[index] = 1.0;
...
}

....
double array[100];
n = func(&array);

This time, we are passing a pointer to a 100-element array of double.
Since 100-element array of double is a distinct type, this approach
won't work for arrays of different sizes.

Nov 14 '05 #4

P: n/a
no****@nospam.com wrote:
Hello!

I can pass a "pointer to a double" to a function that accepts
double*, like this:

int func(double* var) {
*var=1.0;
...
}

double var;

n=func(&var);

---

Now I want to pass a pointer to an array of doubles, the size
of the array must not be fixed though:

int func(double[]* array) {
int index;
index=3;
array[index]=1.0;
...
}

double array[100];

n=func(&array);

with the above code the compiler gives me an error. The only
solution that I found so far is this very inelegant one:

int func(void* array) {
int index;
index=3;
*((double*)(array)+index)=1.0;
...
}

double array[100];

n=func(&array);

---

There must be a cleaner way.. but what is it?

I am interested in both C and "C++ only" solutions.

Thanks!
Mike


To pass a pointer to the array, not to the first element do:

int func(double **array) { or func(double **array, unsigned size) }

then you can code:
double array[100];
n = func(&array); { or n = func(&array, 100); }

But why do you require a pointer to the array, and not pointer to first
element??

Nov 14 '05 #5

P: n/a
For a detailed discussion on passing arrays to funtions in C, I
recommend you refer to Expert C Programming by Peter van der Linden
which has an entire chapter discussing arrays & their relationships
with pointers. This will certainly clarify any issues you may have.

Nov 14 '05 #6

P: n/a


Aaron Gage wrote:
no****@nospam.com wrote:
Hello!

I can pass a "pointer to a double" to a function that accepts
double*, like this:

[snip]

To pass a pointer to the array, not to the first element do:

int func(double **array) { or func(double **array, unsigned size) }

then you can code:
double array[100];
n = func(&array); { or n = func(&array, 100); }


This is not correct. The type of &array is "pointer to 100-element
array of double", *not* "pointer to pointer to double". The correct
prototype is

int func(double (*array)[100]);

You would pass a pointer to pointer to double if you were passing a
pointer to the first element of a 2-d array of double, like so:

double array[5][10];
n = func(array, 5, 10);

int func(double **a, size_t d0, size_t d1);

Since the type "100-element array of double" is a distinct type from
"101-element array of double", the type "pointer to 100-element array
of double" is a distinct type from "pointer to 101-element array of
double", so you don't have to pass the size as a separate parameter;
the array size is specified in the prototype:

int func(double (*array)[100])
{
size_t count = sizeof *array / sizeof (*array)[0];
...
}

This means func() can *only* be called with 100-element arrays of
double.

However, this defeats the OP's purpose, which is to be able to deal
with arrays of any size; this is why he needs to pass a pointer to the
first element and the array size as parameters.

Nov 14 '05 #7

P: n/a


jo*******@my-deja.com wrote:

[snip]
double array[100];
int n = func(array, sizeof array);


Dammit, that's a bug. That last line *should* read:

int n = func(array, sizeof array / sizeof array[0]);

Back to your regularly scheduled programming...

Nov 14 '05 #8

P: n/a
> cat main.c
#include <stdlib.h>
#include <stdio.h>

int doubleArray_fprintf( // total number of characters
FILE* fp, // file pointer
const
char* format, // format for elements
size_t columns, // number of columns
const
size_t n, // array size
const
double array[n] // the array to be printed
) {
columns = (0 < columns)? columns: 4;
int total = 0; // total number of characters
for (size_t j = 0; j < n; ++j) {
int characters = fprintf(fp, " ");
if (0 < characters) {
total += characters;
characters = fprintf(fp, format, array[j]);
if (0 < characters) {
total += characters;
size_t k = j + 1;
if (0 == k%columns && k < n) {
characters = fprintf(fp, "\n");
if (0 < characters) {
total += characters;
}
else {
total = characters;
break;
}
}
}
else {
total = characters;
break;
}
}
else {
total = characters;
break;
}
}
return total;
}

int main(int argc, char* argv[]) {
const
size_t n = 10;
double array[n];
for (size_t j = 0; j < n; ++j) {
array[j] = j;
}

doubleArray_fprintf(stdout, "%g", 5, n, array);
fprintf(stdout, "\n");

return 0;
}
gcc -Wall -std=c99 -pedantic -o main main.c
./main

0 1 2 3 4
5 6 7 8 9
Nov 14 '05 #9

P: n/a
Aaron Gage wrote on 27/05/05 :
double array[100];
To pass a pointer to the array, not to the first element do:

int func(double **array) { or func(double **array, unsigned size) }


Nope. You meant

int func(double (*array)[100])

--
Emmanuel
The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
The C-library: http://www.dinkumware.com/refxc.html

"C is a sharp tool"

Nov 14 '05 #10

P: n/a
jo*******@my-deja.com writes:
Aaron Gage wrote:
no****@nospam.com wrote:
Hello!

I can pass a "pointer to a double" to a function that accepts
double*, like this:


[snip]

To pass a pointer to the array, not to the first element do:

int func(double **array) { or func(double **array, unsigned size) }

then you can code:
double array[100];
n = func(&array); { or n = func(&array, 100); }


This is not correct. The type of &array is "pointer to 100-element
array of double", *not* "pointer to pointer to double". The correct
prototype is

int func(double (*array)[100]);


That's one correct prototype. Another one is:

int func( double (*array)[] );

Or, perhaps more usefully:

int func( double (*array)[], unsigned index_limit );

This allows arrays of all sizes to be passed. And, it offers a
potentially useful check, in that only arrays can be passed. So, if
we have:

#define FUNC(a) ( func( &(a), sizeof( a ) / sizeof *(a) ) )

then FUNC will work on arrays, but pointers will get (are required to
get?) a diagnostic about "incompatible types".
Nov 14 '05 #11

This discussion thread is closed

Replies have been disabled for this discussion.