0

If I have a big 1d array declared like this

1darray = malloc(N*sizeof(double))

and I have another structure declared like this

for j:A

  2dstructure[j] = malloc(C[j]*sizeof(double*))     

  for i:B

    2dstructure[j][i] = malloc(D*sizeof(double))

  end
end

And the size of A*B = N, that means sizeof(1darray) == sizeof(2dstructure)

Is there a way I can copy what I have in 1d array to the 2d structure without using a loop?

6
  • 1
    Try memcpy(1darray, 2darray, sizeof(1darray[0]), lengthOf1DArray)? Commented May 29, 2013 at 18:21
  • hmmm but wouldn't the memory not being contiguous as the below comment mentions be a problem? Commented May 29, 2013 at 18:26
  • 1
    then i suppose there's no way around without a loop. Commented May 29, 2013 at 18:33
  • A pointer to pointer is not a 2D array. C has natively 2D arrays that are contiguous in memory, why not use these? Commented May 29, 2013 at 19:01
  • 1
    In function scope you can just to double (*A)[n] = malloc(sizeof(double[m][n])); and by that have a contiguous allocation where you can address elements simply through A[i][j]. Commented May 29, 2013 at 22:02

3 Answers 3

3

Yes, you can map your 2D indices to a linear 1D index thus:

int idx = j*B + i;

At that point, 1darray[idx] is equivalent to 2dstructure[j][i].

Sign up to request clarification or add additional context in comments.

2 Comments

sorry I didn't explain myself very well. What I want is to copy what I have in the 1d array into the 2d structure without using loops.
@Atirag: No, because your code above doesn't really create a 2D structure, it creates an array of pointers to arrays. The corresponding memory will not be contiguous.
2

Assuming you have an 1D N-element array initialised like this:

double *onedarray = malloc(N*sizeof(double));

And you want to create a 2D AxB element array, where A*B = N. You could create the data for the 2D array as a contiguous block of memory like this:

double *twoddata = malloc(A*B*sizeof(double));

And then create the structure separately, like this:

double **twodstructure = malloc(A*sizeof(double*));
for (int i = 0; i < A; i++)
  twodstructure[i] = &twoddata[i*B];

Then copying from the 1D array to the 2D array, is a simple memcpy:

memcpy(twoddata, onedarray, N*sizeof(double));

And you can access your 2D array in a structured manner with code like this:

for (int i = 0; i < A; i++)
  for (int j = 0; j < B; j++)
    printf("%f\n", twodstructure[i][j]);

1 Comment

In C, don't cast the return of malloc: stackoverflow.com/questions/605845/…
1

With your allocation pattern, you can't do a simple copy because of the multiple allocations in the second loop. It depends on what you're really after. You can arrange things so that you do just one allocation of a set of pointers — by setting up pointers into your current 1D array so that you can access it as a 2D array. Alternatively, you can create a copy of your 1D array and then set up the pointers (2 allocations, 1 copy, 1 initialization loop). Since the only issue is whether to copy the original allocation, the main answer will work on the original data.

You have:

int N, A, B;
A = ...;
B = ...;
N = A * B;

double *a_1d = malloc(N * sizeof(double));

...check and load a_1d...

Now you can create a 2D 'array' by:

double **a_2d = malloc(A * sizeof(double *));

...check that allocation succeeded...

for (int i = 0; i < A; i++)
    a_2d[i] = &a_1d[i * B];

With this initialization done, you can now use:

for (int i = 0; i < A; i++)
    for (int j = 0; j < B; j++)
        a_2d[i][j] = ...;

If you really need to duplicate the original a_1d array, you'd add:

double *a_1d_copy = malloc(N * sizeof(double));
...check that the allocation succeeded...
memmove(a_1d_copy, a_1d, N * sizeof(double));

and then you can reference a_1d_copy instead of a_1d in setting up a_2d.

Remember that when it comes time to free things, you need to release both a_1d and a_2d (and a_2d_copy if you're using that).

Comments

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.