0

I have the function and main

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <sys/time.h>

setArray(double *thearray){
    *thearray[0][0] = 2.0;
    *thearray[0][1] = 2.0;
    *thearray[1][0] = 2.0;
    *thearray[1][1] = 2.0;
}

void main(){
    double myarray[2][2];
    setArray(&myarray);
}

I cannot specify the size of array on setArray function because I don't know what will it be. I need to fill up the array in this specific fucction but I can't. get errors:

test.c: In function ‘setArray’:
test.c:8:13: error: subscripted value is neither array nor pointer nor vector
test.c:9:13: error: subscripted value is neither array nor pointer nor vector
test.c:10:13: error: subscripted value is neither array nor pointer nor vector
test.c:11:13: error: subscripted value is neither array nor pointer nor vector
test.c: In function ‘main’:
test.c:16:1: warning: passing argument 1 of ‘setArray’ from incompatible pointer type [enabled by default]
test.c:7:1: note: expected ‘double *’ but argument is of type ‘double (*)[2][2]’
2
  • try without the & setArray(myarray) Commented Apr 13, 2014 at 1:01
  • same errors with and without & Commented Apr 13, 2014 at 1:17

4 Answers 4

2

You can use a VLA:

void setArray(int m, int n, double arr[m][n])
{
    for (int r = 0; r < m; ++r)
        for (int c = 0; c < n; ++c)
             arr[r][c] = 2.0;
}

int main()
{
    double myarray[2][2];
    setArray(2, 2, myarray);
}

VLAs are supported in C99, and optional in C11. If your compiler does not support VLAs, then you cannot fulfil your requirements. However, you could pass the array as a 1-D array and find the right elements using arithmetic:

void setArray(int num_rows, int num_cols, double *arr)
{
#define ARR_ACCESS(arr, x, y) ((arr)[(x) * num_cols + (y)])
    for (int r = 0; r < num_rows; ++r)
        for (int c = 0; c < num_cols; ++c)
             ARR_ACCESS(arr, r, c) = 2.0;
#undef ARR_ACCESS
}

int main()
{
    double myarray[2][2];
    setArray(2, 2, (double *)&myarray);
}
Sign up to request clarification or add additional context in comments.

4 Comments

What does VLA stand for?
Variable-Length Array. They were add to the C standard in 1999 (perhaps in an effort to get Fortran people to switch over to C), but compiler vendors were slow to comply with the standard, so VLA support is not as universal as it should be.
@MattMcNabb : Before you posted your solution, I tried using "double **thearray" as the parameter, and removing the dereferences from the original function body. This compiled but had a segmentation fault. Can you explain why? I clearly see why your solution is safer(/better), but I thought passing "myarray" as the **double would work, and can't see why it seg faults.
See c-faq.com/aryptr/pass2dary.html . Basically there are no pointers to point to . In double **x, x must point to some storage that contains a double *. However there is no such storage in your array (array-pointer decay is a temporary thing that happens at runtime).
0

Try this:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <sys/time.h>

void setArray(double **thearray){
    thearray[0][0] = 2.0;
    thearray[0][1] = 2.0;
    thearray[1][0] = 2.0;
    thearray[1][1] = 2.0;
}

void main(){
    int i;
    double **myarray = (double**) malloc(2 * sizeof(double*));
    for(i = 0; i < 2; ++i)
        myarray[i] = (double*) malloc(2 * sizeof(double));
    setArray(myarray);
}

3 Comments

test.c: In function ‘main’: test.c:16:5: warning: passing argument 1 of ‘setArray’ from incompatible pointer type [enabled by default] test.c:7:6: note: expected ‘double *’ but argument is of type ‘double ()[2]’
Try using dynamic memory. That worked for me. If you don't know the size of your array (as I saw in other comments), you will have to keep track of the size some how. Also why was this downvoted?
Downvoted your original version as it didn't have a hope of working. Have un-down voted now, but don't cast the result of malloc.
0

First, your setarray should accept a 2D array, not a poniter. If you know the width of the array, you can define it like this:

void setArray(double (*thearray)[2]) //2D array decays into a pointer to an array

then just call:

setArray(myarray)

An array decays to a pointer only once, so a 2D array wouldn't decay to a pointer to pointer. if the width isn't fixed, use a pointer of pointer instead:

void setArray(double **thearray)
{
    ...
}

setArray((double **)myarray) //explicitly convert.

1 Comment

don't know the size of the array, it could be 2 but it could be 5 so I cant define void setArray(double (*thearray)[2])
-1

A 2D array has a double pointer (**). When you are sending the array as an argument, you do not need to add the ampersand as the array without its brackets is an address.

4 Comments

I also forgot to add that you should not dereference the arrays (put a * in front of them) when you are assigning them.
The two pairs of brackets dereference just how a * does.
The second pair of brackets dereferences a temporary pointer created by the first dereference.
Maybe useful (although this isn't a particularly great explanation either), c-faq.com/aryptr/pass2dary.html

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.