Dynamically creating a contiguous 5D array? [closed] - arrays

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I am working with a very large 5D array that I need to read into contiguous memory (another 5D array). I cannot place the array on the stack because it is too large and creates seg faults. What I've done is to create a 5D array dynamically with malloc however I've found that it is not contiguous memory. Is there an elegant solution to this or is it going to be messy no matter what?

From Jens Gustedt: Don't use fake matrices.
Allocate a 5-dimensional matrix with dimensions A x B x C x D x E (dimensions aren't required to be known at compile time) like so:
float (*matrix5d)[B][C][D][E] = malloc(sizeof(float[A][B][C][D][E]));
Release the memory with a single call to free.
free(matrix5d);
Note that the above requires C99 or higher for variable-length arrays.

Being represented via a contiguous chunk of memory is one of the distinguishing properties of a C array. Multidimensional arrays are arrays of arrays, and therefore contiguous the same as any other array, so if you want a genuine 5D array then you certainly do need contiguous memory for it. As some of the other answers have observed, to ensure that you get a contiguous block of memory, you must allocate the whole thing at once.
Although you can form data structures consisting of arrays of pointers to [[arrays of pointers to [arrays of pointers to ...]] arrays, these are not the same thing at all, just as pointers are not arrays. You can use the indexing operator, [], with such data structures in the same way that you can do with multi-dimensional arrays, but that doesn't make them the same thing.
#EvelynParenteau suggested simulating your 5D array with a 1D array, and indeed that's one way to satisfy your contiguity requirement. You could even write macros to make indexing into such an array easier.
But as long as you are using at least C99, you can dynamically allocate a genuine 5D array. The general form might look something like this:
void allocate_5d(unsigned dim1, unsigned dim2, unsigned dim3, unsigned dim4,
unsigned dim5, double (**aptr)[dim2][dim3][dim4][dim5]) {
*aptr = malloc(dim1 * sizeof(**aptr));
}
It would be used like this:
void do_something(unsigned dim1, unsigned dim2, unsigned dim3, unsigned dim4,
unsigned dim5) {
double (*array)[dim2][dim3][dim4][dim5];
allocate_5d(dim1, dim2, dim4, dim4, dim5, &array);
if (!array) {
// Handle allocation failure ...
}
array[0][0][0][0][0] = 42;
// ...
free(array);
}
If dimensions 2 - 5 are compile-time constants, then you can even do a this (slightly differently) in C90, but the variation presented above depends on variable-length arrays, which were new in C99.

There is a way to make the memory contiguous, but whether its elegant or messy I'll leave up to you ;)
First, let's consider the case of a 1 dimensional array. In this case, it's trivial to get contiguous memory; the memory you get from malloc will be contiguous. It seems simple enough, but we're going to later use this fact to get a 5 dimensional contiguous array.
Now, let's consider a 2 dimensional array that is M by N in size. Here's one way of creating one (assuming we're using floats).
float** array2d = malloc(M * sizeof(float*));
for (int i = 0; i < M; i++) {
array2d[i] = malloc(N * sizeof(float));
}
Strictly speaking, this is not a two dimensional array, it's an array of arrays. Now, we can access elements of array2d like array2d[0][0], array2d[0][1] etc. Conceptually this is very nice, but as you've noted, we don't necessarily have contiguous memory since we did multiple calls to malloc. What we need is a way to allocate all of the memory necessary to store M*N floats in one call to malloc.
float* array2d = malloc(M * N * sizeof(float));
Note that in this form, array2d is float* instead of float**, i.e. it's an array of floats, not an array of arrays of floats. So, we can't do array2d[0][0] any more. How do we now index this array?
It's entirely up to us to decide how this 2 dimensional array is laid out in memory. Let's say that M is the "width" of the array (meaning the number of elements in a row) and that N is the "height" of the array (meaning the number of rows in the array). Also, let's just say that the first M entries in the array are the first row, the next M entries are the second row, etc. So to read the entry at row y, column x, we would do this:
float data = array2d[y * M + x];
Say we want element (0, 0). Then y * M + x simply becomes 0, so we're good. Now say we want element (1, 0) (i.e. the first element in the second row). Then, y * M + x becomes M, which as we've decided above is where the second row starts.
We can generalize this approach to higher dimensions. Let's say we have a three dimensional array of size L by M by N. You can think of this as L two dimensional arrays laid out sequentially in memory, all of size M by N. Then, to access element (x, y, z) we would do:
float data = array3d[z * (M * N) + y * (M) + x];
Conceptually you can think of this as skipping the first z two dimensional arrays, then skipping the first y rows of that array, and then going to the xth element of that row. For more dimensions, there are more multiplicative terms when indexing, but the approach is fundamentally the same.

One way of thinking about it is to use malloc to allocate a 1d array of 4d arrays, because fundamentally malloc can only allocate 1d arrays, and an N-d array is just 1d array of (N-1)-d arrays.
However, just like any array allocated by malloc, the "array object" is actually a pointer, so you shouldn't use sizeof() to get the size of the array.
#include <stdio.h>
#include <stdlib.h>
typedef int Array_4D_Type[4][3][2][1];
int main(void) {
Array_4D_Type *arr = malloc(5 * sizeof(Array_4D_Type));
// ^^^^^^^^^^^^^^^^ here, allocate a length-5 vector of 4d array type
int *p = &arr[0][0][0][0][0];
for (int i = 0 ; i < 120 ; i++){
p[i] = i;
}
printf("arr_start = %d, end = %d\n", arr[0][0][0][0][0], arr[4][3][2][1][0]);
return 0;
}
You can test the code here.
Update:
As is mentioned in the comments, using typedef here forces the array to be static sized except the top dimension.
The use of typedef here is only to make the pointer-to-array syntax a little cleaner.
However, with VLA enabled, int (*arr)[n][o][p][q] = malloc(m*sizeof(*arr)); should still work and allow you to specify dynamic size on each dimension.

With dynamic allocation, using malloc:
int** x;
x = malloc(dimension1_max * sizeof(int*));
for (int i = 0; i < dimension1_max; i++) {
x[i] = malloc(dimension2_max * sizeof(int));
}
[...]
for (int i = 0; i < dimension1_max; i++) {
free(x[i]);
}
free(x);
This allocates an 2D array of size dimension1_max * dimension2_max. So, for example, if you want a 640*480 array (f.e. pixels of an image), use dimension1_max = 640, dimension2_max = 480. You can then access the array using x[d1][d2] where d1 = 0..639, d2 = 0..479.
But a search on SO or Google also reveals other possibilities, for example in this SO question
Note that your array won't allocate a contiguous region of memory (640*480 bytes) in that case which could give problems with functions that assume this. So to get the array satisfy the condition, replace the malloc block above with this:
int** x;
int* temp;
x = malloc(dimension1_max * sizeof(int*));
temp = malloc(dimension1_max * dimension2_max * sizeof(int));
for (int i = 0; i < dimension1_max; i++) {
x[i] = temp + (i * dimension2_max);
}
[...]
free(temp);
free(x);
on similar way you can build dynamically 5d array

If I understand your question, that you have a current 5D array, and you need to allocate storage for, and make a copy of that array, and then you wish to access the values in a sequential manner. As others have noted, the approach is to use a pointer to a 4D array to allocate a block of memory dim1 * sizeof 4D to hold your existing array. (you can think about is as allocating for dim1 rows of what makes up your 5D array). You can then simply copy the existing array, (using memcpy or the like) then and assign a pointer to the first element for sequential access.
The benefit is you allocate a single block to hold a copy of your existing array. This will require only a single free when you are done making use of the copy.
This does not work with fake (pointer to pointer to pointer... collections of memory)
Below is a short example of creating a dim1 pointers to what makes up the remaining 4d of your existing array (in a single block allocation) where all but your dim1 dimensions are known at compile time. The existing 5D array a is copied to a new block of memory assigned to b. An integer pointer 'p' is then assigned the beginning address of b. The values of b are accessed sequentially through pointer p.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main (void) {
int a[2][2][2][2][2] = { { { {{1,2}, {3,4}}, /* 5D Array */
{{5,6}, {7,8}} },
{ {{1,2}, {3,4}},
{{5,6}, {7,8}} } },
{ { {{1,2}, {3,4}},
{{5,6}, {7,8}} },
{ {{1,2}, {3,4}},
{{5,6}, {7,8}} } } };
/* ptr to 5D, ptr to int* */
int (*b)[2][2][2][2] = NULL, *p = NULL;
/* allocate block to hold a */
b = malloc (sizeof a/sizeof *a * sizeof *b);
memcpy (b, a, sizeof a/sizeof *a * sizeof *b); /* copy a to b */
p = ****b; /* assign address of first element */
printf ("\nb:\n"); /* ouput using sequential access */
for (int i = 0; i < (int)(sizeof a/sizeof *****a); i++)
printf (" *(p + %2d) : %d\n", i, p[i]);
free (b); /* single free is all that is required */
return 0;
}
Example Use/Output
$ ./bin/arr5dstatic1
b:
*(p + 0) : 1
*(p + 1) : 2
*(p + 2) : 3
*(p + 3) : 4
*(p + 4) : 5
*(p + 5) : 6
*(p + 6) : 7
*(p + 7) : 8
*(p + 8) : 1
*(p + 9) : 2
*(p + 10) : 3
*(p + 11) : 4
*(p + 12) : 5
*(p + 13) : 6
*(p + 14) : 7
*(p + 15) : 8
*(p + 16) : 1
*(p + 17) : 2
*(p + 18) : 3
*(p + 19) : 4
*(p + 20) : 5
*(p + 21) : 6
*(p + 22) : 7
*(p + 23) : 8
*(p + 24) : 1
*(p + 25) : 2
*(p + 26) : 3
*(p + 27) : 4
*(p + 28) : 5
*(p + 29) : 6
*(p + 30) : 7
*(p + 31) : 8
There is good reason that the rest of the comments and answers suggest you find some way other than using a 5D array setup. It would be worth while to investigate if you can modify whatever is producing the data you capture in your original 5D array to output the data in some other format.

Related

C - appending a row to a matrix

Is it possible to append a row/column to a matrix in C without for loops? I am having a matrix float A[4][4] and would like to append a float vector to it b[1][4] so that I would obtain M = [A; b] - b being the last row - is it doable in C?
No, size of an array depends on its type and automatic objects cannot change their type during their lifetime.
However, the situation is different for dynamic array. If the array was allocated as a sequence of float[4] 1d arrays i.e. with:
float (*A)[4] = malloc(4 * sizeof *A);
then a new row can be extended with realloc():
A = realloc(A, 5 * sizeof *A);
Usually you should check if the reallocation succeeded. If it fails the pointer A would be overwritten leading to a memory leak. Therefore the better code would be:
float (*newA)[4] = realloc(A, 5 * sizeof *A);
if (!newA) { ... handle error ... }
A = newA;

Use array annotation with pointers

I have currently trouble understanding the following scenario:
I have a multidimensional array of Strings and I want to address it by using pointers only but I always get a Segmentation Fault when using the array annotation on the pointer. This is just an example code I want to use the 3D array in a pthread so I want to pass it in via a structure as a pointer but it just doesn't work and I would like to know why? I thought pointers and arrays are functionally equivalent? Here is the sample code:
#include <stdio.h>
void func(unsigned char ***ptr);
int main() {
// Image of dimension 10 times 10
unsigned char image[10][10][3];
unsigned char ***ptr = image;
memcpy(image[0][0], "\120\200\12", 3);
// This works as expected
printf("Test: %s", image[0][0]);
func(image);
return 0;
}
void func(unsigned char ***ptr) {
// But here I get a Segmentation Fault but why??
printf("Ptr: %s", ptr[0][0]);
}
Thanks in advance for your help :)
I think maybe strdup confuses the issue. Pointers and arrays are not always equivalent. Let me try to demonstrate. I always avoid actual multi-dimension arrays, so I may make a mistake here, but:
int main()
{
char d3Array[10][10][4]; //creates a 400-byte contiguous memory area
char ***d3Pointer; //a pointer to a pointer to a pointer to a char.
int i,j;
d3Pointer = malloc(sizeof(char**) * 10);
for (i = 0; i < 10; ++i)
{
d3Pointer[i] = malloc(sizeof(char*) * 10);
for (j = 0; j < 4; ++j)
{
d3Pointer[i][j] = malloc(sizeof(char) * 4);
}
}
//this
d3Pointer[2][3][1] = 'a';
//is equivalent to this
char **d2Pointer = d3Pointer[2];
char *d1Pointer = d2Pointer[3];
d1Pointer[1] = 'a';
d3Array[2][3][1] = 'a';
//is equivalent to
((char *)d3Array)[(2 * 10 * 4) + (3 * 4) + (1)] = 'a';
}
Generally, I use the layered approach. If I want contiguous memory, I handle the math myself..like so:
char *psuedo3dArray = malloc(sizeof(char) * 10 * 10 * 4);
psuedo3dArray[(2 * 10 * 4) + (3 * 4) + (1)] = 'a';
Better yet, I use a collection library like uthash.
Note that properly encapsulating your data makes the actual code incredibly easy to read:
typedef unsigned char byte_t;
typedef struct
{
byte_t r;
byte_t g;
byte_t b;
}pixel_t;
typedef struct
{
int width;
int height;
pixel_t * pixelArray;
}screen_t;
pixel_t *getxyPixel(screen_t *pScreen, int x, int y)
{
return pScreen->pixelArray + (y*pScreen->width) + x;
}
int main()
{
screen_t myScreen;
myScreen.width = 1024;
myScreen.height = 768;
myScreen.pixelArray = (pixel_t*)malloc(sizeof(pixel_t) * myScreen.height * myScreen.width);
getxyPixel(&myScreen, 150, 120)->r = 255;
}
In C, you should allocate space for your 2D array one row at a time. Your definition of test declares a 10 by 10 array of char pointers, so you don't need to call malloc for it. But to store a string you need to allocate space for the string. Your call to strcpy would crash. Use strdup instead. One way to write your code is as follows.
char ***test = NULL;
char *ptr = NULL;
test = malloc(10 * sizeof(char **));
for (int i = 0; i < 10; i++) {
test[i] = malloc(10 * sizeof(char *));
}
test[0][0] = strdup("abc");
ptr = test[0][0];
printf("%s\n", ptr);
test[4][5] = strdup("efg");
ptr = test[4][5];
printf("%s\n", ptr);
Alternatively, if you want to keep your 10 by 10 definition, you could code it like this:
char *test[10][10];
char *ptr = NULL;
test[0][0] = strdup("abc");
ptr = test[0][0];
printf("%s\n", ptr);
test[4][5] = strdup("efg");
ptr = test[4][5];
printf("%s\n", ptr);
Your problem is, that a char[10][10][3] is something very different from a char***: The first is an array of arrays of arrays, the later is a pointer to a pointer to a pointer. The confusions arises because both can be dereferenced with the same syntax. So, here is a bit of an explanation:
The syntax a[b] is nothing but a shorthand for *(a + b): First you perform pointer arithmetic, then you dereference the resulting pointer.
But, how come you can use a[b] when a is an array instead of a pointer? Well, because...
Arrays decay into pointers to their first element: If you have an array declared like int array[10], saying array + 3 results in array decaying to a pointer of type int*.
But, how does that help to evaluate a[b]? Well, because...
Pointer arithmetic takes the size of the target into account: The expression array + 3 triggers a calculation along the lines of (size_t)array + 3*sizeof(*array). In our case, the pointer that results from the array-pointer-decay points to an int, which has a size, say 4 bytes. So, the pointer is incremented by 3*4 bytes. The result is a pointer that points to the fourths int in the array, the first three elements are skipped by the pointer arithmetic.
Note, that this works for arrays of any element type. Arrays can contain bytes, or integers, or floats, or structs, or other arrays. The pointer arithmetic is the same.
But, how does that help us with multidimensional arrays? Well, because...
Multidimensional arrays are just 1D arrays that happen to contain arrays as elements: When you declare an array with char image[256][512]; you are declaring a 1D array of 256 elements. These 256 elements are all arrays of 512 characters, each. Since the sizeof(char) == 1, the size of an element of the outer array is 512*sizeof(char) = 512, and, since we have 256 such arrays, the total size of image is 256*512. Now, I can declare a 3D array with char animation[24][256][512];...
So, going back to your example that uses
char image[10][10][3]
what happens when you say image[1][2][1] is this: The expression is equivalent to this one:
*(*(*(image + 1) + 2) + 3)
image being of type char[10][10][3] decays into a pointer to its first element, which is of type char(*)[10][3] The size of that element is 10*3*1 = 30 bytes.
image + 1: Pointer arithmetic is performed to add 1 to the resulting pointer, which increments it by 30 bytes.
*(image + 1): The pointer is dereferenced, we are now talking directly about the element, which is of type char[10][3].
This array again decays into a pointer to its first element, which is of type char(*)[3]. The size of the element is 3*1 = 3. This pointer points at the same byte in memory as the pointer that resulted from step 2. The only difference is, that it has a different type!
*(image + 1) + 2: Pointer arithmetic is performed to add 2 to the resulting pointer, which increments it by 2*3 = 6 bytes. Together with the increment in step 2, we now have an offset of 36 bytes, total.
*(*(image + 1) + 2): The pointer is dereferenced, we are now talking directly about the element, which is of type char[3].
This array again decays into a pointer to its first element, which is of type char*. The size of the element is now just a single byte. Again, this pointer has the same value as the pointer resulting from step 5, but a different type.
*(*(image + 1) + 2) + 1: Pointer arithmetic again, adding 1*1 = 1 bytes to the total offset, which increases to 37 bytes.
*(*(*(image + 1) + 2) + 1): The pointer is dereferenced the last time, we are now talking about the char at an offset of 37 bytes into the image.
So, what's the difference to a char***? When you dereference a char***, you do not get any array-pointer-decay. When you try to evaluate the expression pointers[1][2][1] with a variable declared as
char*** pointers;
the expression is again equivalent to:
*(*(*(pointers + 1) + 2) + 3)
pointers is a pointer, so no decay happens. Its type is char***, and it points to a value of type char**, which likely has a size of 8 bytes (assuming a 64 bit system).
pointers + 1: Pointer arithmetic is performed to add 1 to the resulting pointer, which increments it by 1*8 = 8 bytes.
*(pointers + 1): The pointer is dereferenced, we are now talking about the pointer value that is found in memory at an offset of 8 bytes of where pointers points.
Further steps depending on what actually happened to be stored at pointers[1]. These steps do not involve any array-pointer-decay, and thus load pointers from memory instead.
You see, the difference between a char[10][10][3] and a char*** is profound. In the first case, the array-pointer-decay transforms the process into a pure offset computation into a multidimensional array. In the later case, we repeatedly load pointers from memory when accessing elements, all we ever have are 1D arrays of pointers. And it's all down to the types of pointers!

C - dynamic matrix allocation: something doesn't make sense to me

I was wondering, why does this work
// read n as matrix dimension, then:
int* M;
M = (int*)malloc(n * n * sizeof(int));
// cycle through each "cell" in the matrix and read a number with
scanf("%d", &M[i * n + j]);
and this doesn't?
// read n as matrix dimension, then:
int** M;
M = malloc(n * n * sizeof(int));
// cycle through each "cell" in the matrix and read a number with
scanf ("%d", &M[i][j]);
I just don't get it. In both cases they should be double pointers, am I right?
int ** is supposed to point to an int*. Here you have allocated some memory - to be precise sizeof(int)*rows*cols bytes and then you use M[i] etc. Here M[i] which is basically *(M+i) we will access i*sizeof(int*) offset from the one address returned by malloc but you allocated for rows*cols int's not int*-s - so you will eventually access memory that you shouldn't (typically on a system where sizeof(int*) > sizeof(int)) which will lead you to undefined behavior.
What is the solution then? Well allocate for int*-s.
int ** M = malloc(sizeof *M * rows);
if(!M){
perror("malloc");
exit(EXIT_FAILURE);
}
for(size_t i = 0; i < rows; i++){
M[i] = malloc(sizeof *M[i] * cols);
if(!M[i]){
perror("malloc");
exit(EXIT_FAILURE);
}
}
For your case rows = N and cols = N.
This will you give you a jagged array which you can access like you did. With malloc comes the responsibility of checking the return type of it and freeing the memory when you are done working with it. Do that.
On the first case you are accessing the allocated chunk of memory and you have realized the memory access using indices i and j to give yourself a flavor of accessing memory that you do in case of 2d array. So there is no point using double pointer here. It is legal what you did.
In both cases they should be double pointers
No they shouldn't be. The first one is different than the second one. They are not in anyway indicating the same thing.
Case 1 :-
int* M;
M = (int*)malloc(n * n * sizeof(int));
Here memory is allocated for M which is single pointer. Let's say you want to store 5 integers into that memory. So it looks like
-------------------------------
| 10 | 20 | 30 | 40 | 50 |
-------------------------------
M M[0] M[1] M[2] m[3] M[4] <--- Its a 1D array, only one row of 5 int
Case 2 :-
int **M;
M = malloc(n * n * sizeof(int));
M[0][0] M[0][1]
| | | | ....... | | <---- If below one is not done then how will you store the numbers into these
----------- ----- ---------
| | | |
M[0] M[1] M[2] .... M[4] <--- didn't allocated memory for these rows or 1D array
| | | |
-----------------------------------
|
M <---- allocated memory for this
It doesn't work because M is double pointer and you allocated memory only for M, you didn't allocated memory for M[row]. thats why below statement didn't work.
scanf ("%d", &M[i][j]);
So to make it work first Allocate the memory for M as you did
M = malloc(row*sizeof(*M)); /* row indicates no of rows */
and then allocate for each row
for(int index = 0 ;index < row;index++) {
M[index] = malloc(col * sizeof(*M[index])); /* col indicates number of columns */
}
And scan the matrix input
for(int index = 0 ;index < row;index++) {
for(int sub_index = 0 ;sub_index < col; sub_index++)
scanf("%d",&M[index][sub_index]);
}
and once work is done with matrix free the dynamically allocated memory using free() for each row to avoid memory leakage.
The other answers (suggesting one malloc for M and n mallocs for the rows) are correct, but not the most efficient way to allocate a matrix. You can, however, allocate the matrix with only one malloc call, while still allowing you to index it by row and column with M[i][j], as follows:
int (*M)[cols] = malloc(rows * sizeof *M);
This declares M as a pointer to array of int with length cols and requests malloc to allocate rows number of such arrays, meaning you get a single block of rows * cols ints (sizeof *M == sizeof(int) * cols).
When the malloc succeeds, you can use M as if it were declared as int M[rows][cols] so you can read into it with
scanf("%d", &M[i][j]);
It looks more complicated, but allocates M as one contiguous block of memory, which allows the processor to optimize access to it.
And as an added bonus you can also free it with just one call:
free(M);
This does require C99 support, or at least support for variable-length arrays, but the matrix itself is not a proper variable-length array. It is still allocated by malloc, but the declaration of M allows you to use it like one.

Can anyone help me debug this 2D array?

I am trying to increase the size of my 2D array and hm is a struct that contains the x length of the array. I am using value -99999991 to indicate the end of the array.
Is this the correct way to do it?
hm->value = realloc(hm->value,(hm->x+1)*sizeof(int));
hm->value[hm->x] = malloc(sizeof(int));
hm->value[hm->x][0] = -999999991;
hm->value[hm->x-1] = realloc(hm->value[hm->x-1],2*sizeof(int));
hm->value[hm->x-1][1] = -999999991;
hm->value[hm->x-1][0] = value;
You don't have a 2D array if it can be resized, you have a pointer to a pointer to an int.
An array:
int A[n][m];
Accessing the array: A[2][3] = 4; // Equivalent to *(A + 2*m + 3)
A variable sized 2D "array":
int **A;
A = malloc(n*m*sizeof(int));
A[2][3] = 4; // Equivalent to *A + 2*??? + 3)
The compiler doesn't know if your array is one dimensional, or if it is two dimensional then what the size of the two dimensions are. It can't calculate this any more.
Also, realloc can't put the data in the right place. Consider a 2x2 2D array going to a 2x3 2D array:
int **A = {{0,1}, {2,3}}; // for berevity - this isn't valid C!
// stored in memory as [0,1,2,3]
A = realloc(A, 2*3* sizeof(int));
New array stored in memory is [0,1, , 2, 3, ]; This required copying the data.
There are two decent solutions (though they aren't pretty):
1) Treat your 2D array as a list of 1D arrays
int **A;
A = malloc(m*sizeof(void *));
for (i = 0; i < m; ++i) {
A[i] = malloc (n*sizeof(int);
}
(now realloc should work on both of these arrays, but accessing elements will require two pointer dereferences rather than pointer arithmetic)
2) if one of the dimensions of the array is fixed then we can use a 2D array in memory and realloc it as required.
#define M 16
int **A;
A = malloc(M*n*sizeof(int)); // realloc also works
// access an element:
*(A + 3*M + 2) = 4; // (3*M is compile time constant)
In this second example we always grow at the end of our 2D array (so my example of going from 2x2 to 2x3 is illegal - the second 2 is a fixed length).

Concatenating 2 arrays without memcpy

Suppose I ve
int *a,*b;
a= malloc(5*sizeof(int));
b= malloc(5*sizeof(int));
and subsequently assign values.
Let a - 1, 2, 3, 4, 5
b - 6, 7, 8, 9, 10
Is there a method to concatenate both these malloced arrays without using further malloc,realloc or memcpy? There shud not be a malloc of 10 locations!
I must be able to get a[8]=9 after executing, without the overhead of moving the arrays.
The language is C
a= malloc(5*sizeof(int));
You only allocated 5 ints to a, so no, you can't do it without some form or memory allocation (malloc / realloc), since a[8] would be illegal to begin with.
I must be able to get a[8]=9 after executing, without the overhead of
moving the arrays
Since since you are working with contiguous memory regions (which you are calling arrays) you will always have some overhead when moving elements around. If you don't need to access elements by their indexes just use linked lists.
If you don't need strict array indexing, you could make a pseudo-linked-list (I know there's a name for this data type but I can't remember it right now):
struct listish {
int *arr
size_t size;
struct listish *next;
};
The "indexing" function would look like this:
int *index(struct listish *list, size_t i)
{
if(list == NULL) return NULL; // index out of bounds
if(i < list->size) return list->arr + i; // return a pointer to the element
else return index(list->next, i - list->size); // not in this array - go to next node
}
The idea is to combine the in-place reordering of a linked list with the contiguous space of an array. In this case, index(list, 4) would return &a[4], and index(list, 5) would return &b[0], simulating continuous indexing without reallocating and moving your entire array - all you need to do is allocate a few small struct listish objects and set them up properly, a task I leave to you.
What you ask can't be done.
You have, maybe, another option.
Just allocate space for 10 values, and make b point to the correct element
int *a = malloc(10 * sizeof *a);
/* error checking missing */
int *b = a + 5;
a[0] = 1; a[1] = 2; a[2] = 3; a[3] = 4; a[4] = 5;
b[0] = 6; b[1] = 7; b[2] = 8; b[3] = 9; b[4] = 10;
printf("a[8] is %d\n", a[8]);

Resources