473,386 Members | 1,817 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,386 software developers and data experts.

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


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
10 9081
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
> 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


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
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
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


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


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
> 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
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
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 thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: Nelson | last post by:
Hi, Can pointers be passed by reference to functions? If so, how to do it? Or is there any other way to change the pointers in the caller by the called function? Thanks, Nelson
5
by: DamonChong | last post by:
Hi, I am still struggling to master C++ and is trying to understand how to achieve passing arguments using pointers. I got some questions that I like to post to the experts here, hope you can...
3
by: mandatory | last post by:
hi, i would like to pass a pointer to a thread function to a class. The function in my code that i would like to get the address of, and pass it to a class function is: DWORD...
5
by: CViniciusM | last post by:
Hello, The output of the code below is: number = 10 number = 0 (or other number except 15) Why the output of the second 'number' is not 15? Why the 'number' address is not changed? Thanks...
1
by: Laszlo Fust | last post by:
Hello! I have a problem with C#. I have a method in an activeX: func(long FAR* pRes, long lBufSize, long FAR* lpNeeded) This activeX have written in VC 6. I should call this method in a C#...
0
by: brckcc | last post by:
I have a function in C which takes a pointer to a pointer to a structure. It then returns a linked list. How do I call, via P/Invoke, from C# to C. struct LinkedList { char *value; struct...
7
by: Naveen koul | last post by:
Sir, I am facing an certain problem , i am trying to convert a piece of code in VisaualC# .hope some body will helpme out about this how can it be done...
1
by: siegfried | last post by:
The std::lower_bound function requires a function pointer as its last argument. This is simple if you don't overload. How do I I call std::lower_bound with the last argument a function pointer...
1
by: mo | last post by:
I have a C++.net wrapper class to a C++ library... A function takes in a pointer in the wrapper... How do I pass that in C#??? Any help would be appreciated, Thank you. // functions in original...
11
by: HSeganfredo | last post by:
Folks, I want to write a init string function that mallocs an area, fills it with a char, sticks a NUL char in the last position and returns it to the user. So far I noticed that my...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
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
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
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...

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.