Removing an array (row) from a 2d array - C Programming - c

Lets say I have a 2d array:
int array[3][3];
with
000
111
222
and I want to remove 000.
I wrote a function:
void remove(int (*array)[3], int index, int array_length)
{
int i;
for(i = index; i < array_length - 1; i++)
{
array[i] = array[i + 1];
}
}
which receives pointer to the first element of the 2d array, index which I want to remove and a length of the array.
In the for loop, I move array at the position index to the next element.
But I receive this error message:
error: assignment to expression with array type
array[i] = array[i + 1];
Why?
How can I remove element and get the 2d array without array at the index? Should I maybe make new 2d array and return it instead of passing pointer of 2d array to the function?

You can do what you originally wanted if you use an array of structs instead of a 2D array.
The C language treats structs as value types so you can copy them with simple and safe assignment (no memcpy needed).
Here's an example with a few tweaks.
//try online here: https://rextester.com/DDHBC95444
#include <stdio.h>
//from Chromium code https://stackoverflow.com/a/1598827/7331858
#define COUNT_OF(x) ((sizeof(x)/sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x])))))
typedef struct row_t {
int columns[3];
} row_t;
void remove_row(row_t * const rows, const size_t row_index, const size_t row_count)
{
for (size_t i = row_index; i < row_count - 1; i++) {
rows[i] = rows[i + 1];
}
}
void print_rows(row_t const * const rows, const size_t row_count)
{
const size_t column_count = COUNT_OF(rows[0].columns);
for (size_t r = 0; r < row_count; r++) {
for (size_t c = 0; c < column_count; c++) {
printf("%02i ", rows[r].columns[c]);
}
printf("\n");
}
}
int main(void)
{
row_t rows[] = { {{0,1,2}}, {{10,11,12}}, {{20,21,22}} };
print_rows(rows, COUNT_OF(rows));
printf("\n'removing' row index 1\n");
remove_row(rows, 1, COUNT_OF(rows));
print_rows(rows, COUNT_OF(rows));
return 0;
}
outputs:
00 01 02
10 11 12
20 21 22
'removing' row index 1
00 01 02
20 21 22
20 21 22

The parameter array is declared as int (*array)[3], so its type is pointer to an array of 3 ints. The type of array[i] is array of int and an array cannot be assigned to. A function to shift the rows of your matrix can be implemented like this:
void remove(int (*array)[3], int index, int array_length)
{
int i, j;
for(i = index; i < array_length - 1; i++) {
for (j = 0; j < 3; ++j)
array[i][j] = array[i + 1][j];
}
}
Note that the function does not really remove the row, just shifts the rows up. So its name is misleading. You must create a new array and copy the old array to the new array except the indicated row to really remove a row and to change the dimensions of the array.
Edit: The name of that function should be changed because the standard library already has a function named remove.
If the array is obtained like that:
int (*array)[3] = malloc(array_length * sizeof *array);
You can shrink the array by calling the realloc:
int (*p)[3] = realloc(array, (array_length - 1) * sizeof *p);
if (p != NULL)
array = p;

int (*array)[3] -> Here, array is a pointer to 3 element integer array.
error: assignment to expression with array type
This is because an array variable is not modifiable/re-assignable like a pointer. Operations that can be performed on an lvalue of array type are: sizeof, unary & and implicit conversion to pointer type.

The error is telling you that C doesn't support array assigning. Your code tries to copy the whole line i + 1 into the line i of the matrix, but C doesn't know how to operate this.
The solution is to iterate through each element of your array, copying one by one.
void remove(int (*array)[3], int index, int array_length)
{
int i, j;
for(i = index; i < array_length - 1; i++)
{
for(j = 0; j < array_length; ++)
{
array[i][j] = array[i + 1][j];
}
}
}
The code above assumes that your matrix is always squared, but you could change its dimension inside j's for loop.

Related

Creating and looping a two-dimensional array from dynamic values in C

I am trying to create a two dimensional array based on two pre-calculated values (here len1 and len2 are const, but they come from another function). When I run this I get segmentation fault. I am very new to C, this is my first task. Can not figure it out from Guides nor SO, anybody around to help me out?
I suppose the dynamic creation of the two dimensional arrays is wrong. But can't find a good example that would work ..
int main() {
int y, x;
int my_val = 10; // dynamnic value calculated by another func
int len1 = 3; // dynamnic value calculated by another func
int len2 = 3; // dynamnic value calculated by another func
int cols = len1 + 1;
int rows = len2 + 1;
int **twodarr = (int **)malloc(rows * cols * sizeof(int));
for (x = 1; x < cols; x++) {
for (y = 1; y < rows; y++) {
twodarr[y][x] = my_val;
}
}
return 0;
}
Arrays have never been first class elements in C, and multi-dimensional ones have even more poor support. Originally, only C used constant sized arrays, because pointer arithmetics was enough for dynamic 1D arrays, and pointers were an essential element of the language.
C99 introduced the concept of Variable Length Arrays which are what #Lundin's answer uses. Unfortunately, C11 defined them as an optional feature, and Microsoft choosed not to support them for compatibility with C++.
If you use a Microsoft compiler or want compability with environments that do not support the optional VLA feature, you will have to use the old linear idiom: you only use 1D arrays and use compound indices computation: the index of element (i, j) is j + i * cols where cols is the size of the second dimension.
Your code could become:
...
int *twodarr = malloc(rows * cols * sizeof(int)); // BEWARE: actualy 1D array!
for (x = 1; x < cols; x++) {
for (y = 1; y < rows; y++) {
twodarr[x + y*cols] = my_val;
}
}
...
You have to allocate each rows
// allocation of cols
int **twodarr = (int **)malloc(cols * sizeof(int*));// note it is sizeof(int*)
// allocation each rows (in each cols)
for (x = 0; x < cols; x++) {
twodarr[x] = (int *)malloc(rows * sizeof(int));
}
The problem is that int **twodarr cannot be used for 2D arrays, it has no relation what-so-ever to them. You need to swap it for a pointer to a 2D array. Or more conveniently, a pointer to a 1D array - a pointer to a row in this case, assuming [rows][cols].
Also, arrays in C start at index 0.
Code with bug fixes & a simple print example:
#include <stdio.h>
#include <stdlib.h>
int main() {
int my_val = 10; // dynamnic value calculated by another func
int len1 = 3; // dynamnic value calculated by another func
int len2 = 3; // dynamnic value calculated by another func
int rows = len2 + 1;
int cols = len1 + 1;
int (*twodarr)[cols] = malloc( sizeof(int[rows][cols]) );
for (int r = 0; r < rows; r++) {
for (int c = 0; c < cols; c++) {
twodarr[r][c] = my_val;
printf("%d ", twodarr[r][c]);
}
puts("");
}
free(twodarr);
return 0;
}
#kcabus had it right...and admittedly the much more readable way for sanity sake.
The other way to go about it would be to declare it as a memory block, but its much more confusing.
such as
int *twodarr = (int*)calloc((rows *
cols), sizeof(int));
// accessed as follows
*(twodarr + rows*r + c) = value;
// rows * position + position 2
// much more confusing.
A third alternative would be to create a struct like POINT (or just use point) and use two values by just creating an array of POINT just as an example. But I assume you don't want to deal with that in a loop...and I don't blame you heh.

How to use pointer to bidimensional array C

How do I edit a value in an array with pointer in C?
int *pointer;
int array[3][1];
I tried this:
int *Pointer
int array[2][2];
Pointer[1][1]= 6;
but when compiling, I get a segmentation fault error. What to do?
Given some array int Array[Rows][Columns], to make a pointer to a specific element Array[r][c] in it, define int *Pointer = &Array[r][c];.
Then you may access that element using *Pointer in an expression, including assigning to *Pointer to assign values to that element. You may also refer to the element as Pointer[0], and you may refer to other elements in the same row as Pointer[y], where y is such that 0 ≤ y+c < Columns, i.e., Pointer[y] remains in the same row of the array.
You may also use Pointer[y] to refer to elements of the array in other rows as long as none of the language lawyers see you doing it. (In other words, this behavior is technically not defined by the C standard, but many compilers allow it.) E.g., after Pointer = &Array[r][c];, Pointer[2*Columns+3] will refer to the element Array[r+2][c+3].
To make a pointer you can use to access elements of the array using two dimensions, define int (*Pointer)[Columns] = &Array[r];.
Then Pointer[x][y] will refer to element Array[r+x][y]. In particularly, after int (*Pointer)[Columns] = &Array[0]; or int (*Pointer)[Columns] = Array;, Pointer[x][y] and Array[x][y] will refer to the same element.
You can access any given element with this syntax: array[x][y].
By the same token, you can assign your pointer to any element with this syntax: p = &array[x][y].
In C, you can often treat arrays and pointers as "equivalent". Here is a good explanation:
https://eli.thegreenplace.net/2009/10/21/are-pointers-and-arrays-equivalent-in-c
However, you cannot treat a simple pointer as a 2-d array. Here's a code example:
/*
* Sample output:
*
* array=0x7ffc463d0860
* 1 2 3
* 4 5 6
* 7 8 9
* p=0x7ffc463d0860
* 0x7ffc463d0864:1 0x7ffc463d0868:2 0x7ffc463d086c:3
* 0x7ffc463d0870:4 0x7ffc463d0874:5 0x7ffc463d0878:6
* 0x7ffc463d087c:7 0x7ffc463d0880:8 0x7ffc463d0884:9
*/
#include <stdio.h>
int main()
{
int i, j, *p;
int array[3][3] = {
{1,2,3},
{4,5,6},
{7,8,9}
};
// Dereference 2-D array using indexes
printf("array=%p\n", array);
for (i=0; i < 3; i++) {
for (j=0; j < 3; j++)
printf ("%d ", array[i][j]);
printf ("\n");
}
// Dereference 2-D array using pointer
p = &array[0][0];
printf("p=%p\n", p);
for (i=0; i < 3; i++) {
for (j=0; j < 3; j++)
printf ("%p:%d ", p, *p++);
printf ("\n");
}
/* Compile error: subscripted value p[0][0] is neither array nor pointer nor vector
p = &array[0][0];
printf("p=%p, p[0]=%p, p[0][0]=%p\n", p, &p[0], &p[0][0]);
*/
return 0;
}
Cast the 2D-array into 1D-array to pass it to a pointer,
And then, You are ready to access array with pointer. You can use this method to pass 2D-array to a function too.
#include <stdio.h>
int main()
{
int arr[2][2];
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 2; j++)
{
arr[i][j] = (2 * i) + j;
}
}
int *Pointer = (int *)arr; // Type conversion
/*
&arr[0][0] = Pointer + 0
&arr[0][1] = Pointer + 1
&arr[1][2] = Pointer + 2
&arr[2][2] = Pointer + 3
Dereference Pointer to access variable behind the address
*(Pointer + 0) = arr[0][0]
*(Pointer + 1) = arr[0][1]
*(Pointer + 2) = arr[1][2]
*(Pointer + 3) = arr[2][2]
*/
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 2; j++)
{
printf("%d ", *(Pointer + (2 * i) + j)); // Accessing array with pointer
}
printf("\n");
}
return 0;
}
Using the function wv_matalloc from https://www.ratrabbit.nl/ratrabbit/content/sw/matalloc/introduction , you can write the following code:
#include <stdio.h>
#include "wv_matalloc.h"
int main()
{
double **matrix;
int m = 3;
int n = 4;
// allocate m*n matrix:
matrix = wv_matalloc(sizeof(double),0,2,m,n);
// example of usage:
int i,j;
for (i=0; i<m; i++)
for (j=0; j<n; j++)
matrix[i][j] = i*j;
printf("2 3: %f\n",matrix[2][3]);
}
Compile with:
cc -o main main.c wv_matalloc.c
1.
You never assigned a value to Pointer in your example. Thus, attempting to access array by Pointer invokes undefined behavior.
You need to assign Pointer by the address of the first element of array if the pointer shall be a reference:
Pointer = *array;
2.
You can't use 2D notation (p[1][1]) for a pointer to int. This is a C syntax violation.
3.
Since rows of static 2D arrays are allocated subsequent in memory, you also can count the number of array elements until the specific element of desire. You need to subtract the count by 1 since indexing start at 0, not 1.
How does it work?
Each row of array contains 2 elements. a[1][1] (the first element of the second row) is directly stored after the first two.
Note: This is not the best approach. But worth a note beside all other answers as possible solution.
#include <stdio.h>
int main (void)
{
int *Pointer;
static int array[2][2];
Pointer = *array;
Pointer[2] = 6;
printf("array[1][1] (by pointer) = %d\n", Pointer[3]);
printf("array[1][1] (by array istelf) = %d\n", array[1][1]);
}
Output:
array[2][2] (by pointer) = 6
array[2][2] (by array istelf) = 6
Side Notes:
To address the first element of the second row by array[1][2] invokes undefined behavior. You should not use this way.
"but when compiling, I get a segmentation fault error."
Segmentation fault error do not occur at compile time. They occur at run time. It just gives you the impression because high probably your implementation immediately executes the program after compilation.

Differences between matrix implementation in C

I created two 2D arrays (matrix) in C in two different ways.
I don't understand the difference between the way they're represented in the memory, and the reason why I can't refer to them in the same way:
scanf("%d", &intMatrix1[i][j]); //can't refer as &intMatrix1[(i * lines)+j])
scanf("%d", &intMatrix2[(i * lines)+j]); //can't refer as &intMatrix2[i][j])
What is the difference between the ways these two arrays are implemented and why do I have to refer to them differently?
How do I refer to an element in each of the arrays in the same way (?????? in my printMatrix function)?
int main()
{
int **intMatrix1;
int *intMatrix2;
int i, j, lines, columns;
lines = 3;
columns = 2;
/************************* intMatrix1 ****************************/
intMatrix1 = (int **)malloc(lines * sizeof(int *));
for (i = 0; i < lines; ++i)
intMatrix1[i] = (int *)malloc(columns * sizeof(int));
for (i = 0; i < lines; ++i)
{
for (j = 0; j < columns; ++j)
{
printf("Type a number for intMatrix1[%d][%d]\t", i, j);
scanf("%d", &intMatrix1[i][j]);
}
}
/************************* intMatrix2 ****************************/
intMatrix2 = (int *)malloc(lines * columns * sizeof(int));
for (i = 0; i < lines; ++i)
{
for (j = 0; j < columns; ++j)
{
printf("Type a number for intMatrix2[%d][%d]\t", i, j);
scanf("%d", &intMatrix2[(i * lines)+j]);
}
}
/************** printing intMatrix1 & intMatrix2 ****************/
printf("intMatrix1:\n\n");
printMatrix(*intMatrix1, lines, columns);
printf("intMatrix2:\n\n");
printMatrix(intMatrix2, lines, columns);
}
/************************* printMatrix ****************************/
void printMatrix(int *ptArray, int h, int w)
{
int i, j;
printf("Printing matrix...\n\n\n");
for (i = 0; i < h; ++i)
for (j = 0; j < w; ++j)
printf("array[%d][%d] ==============> %d\n, i, j, ??????);
}
You are dereferencing the Matrix1 two times..
Matrix1[i][j] ;
It means that it is a 2D array or a double pointer declared like this.
int **Matrix1 ;
A double pointer could be thought of as array of pointers. Its each element is a pointer itself, so it is dereferenced once to reach at the pointer element, and dereferenced twice to access the data member of that member pointer or array. This statement as you you wrote is equivalent to this one..
Matrix1[i][j] ; //is ~ to
*( *(Matrix1 + i) + j) ;
For a single pointer like this.
int *Matrix2 ;
You can derefernce it only once, like this.
Matrix2[i] ; //is ~ to
*(Matrix2 + i) ;
This statement which you wrote..
Matrix2[(i * lines)+j] ;
|-----------|
This portion evaluates to a single number, so it derefenced one time.
(i * lines) + j ;
As for your printmatrix() function, the ptArray passed to it is a single pointer. So you cannot dereference it twice.
Perhaps you can get better understanding of static and dynamic 2D arrays from my answer here.
2D-array as argument to function
Both matrices are sequences of bytes in memory. However, the difference between them is how you're defining the memory interface to represent a matrix. In one case you're just defining a memory segment with a number of elements equal to the elements in the matrix, and in the other case you're specifically allocating memory to represent each specific line.
The following case is more expensive computationally, because you're invoking malloc() a greater number of times:
intMatrix1 = (int **)malloc(lines * sizeof(int *));
for (i = 0; i < lines; ++i)
intMatrix1[i] = (int *)malloc(columns * sizeof(int));
However, it brings the advantage that you get to refer to matrix elements in a clearer fashion:
intMatrix1[i][j];
If you just allocate one sequence of elements equal to the number of elements in the matrix, you have to take in account line/column index calculations to refer to the right matrix elements in memory.
To attempt to increase the degree of uniformity in the code, may I suggest a function that receives the matrix line reference and matrix column-count and prints a line?
void PrintLine(int *ptrLine, int lineLen) {
unsigned int i;
for(i = 0; i < lineLen; i++)
printf("%d ", ptrLine[i]);
printf("\n");
}
And then, for each matrix type, you would just do:
// Case 1
for(i = 0; i < lines; i++)
PrintLine(intMatrix1[i], columns);
// Case 2
for(i = 0; i < lines; i++) {
PrintLine(intMatrix2 + i*columns, columns);
}
In C, the array access operator [] is really just a cleaner way of performing pointer arithmetic. For a one-dimensional array of elements of type type_s, arr[i] is equivalent to *(arr + (i * sizeof(type_s))). To dissect that expression:
arr will be the base address, the lowest memory address where this array is stored
i is the zero-indexed position of the element in the array
sizeof returns the number of chars (which is generally the same as the number of bytes, but it's not mandated by the C spec) that an element in arr takes up in memory. The compiler will determine the size of the element and take care of performing this math for you.
As a side note, this syntax has the side effect of arr[i] being equivalent to i[arr], although it's universally accepted to put the index in brackets.
So with all of that said, let's look at the differences between your two declarations:
intMatrix1[i][j] is equivalent to *(*(intMatrix1 + i * sizeof(int)) + j * sizeof(int)). So, there are two dereference operators in that expression, meaning that intMatrix is an array of arrays (it contains pointers to pointers).
On the other hand, intMatrix2[(i * lines)+j] is equivalent to *(intMatrix2 + ((i * lines) + j) * sizeof(int)), which contains only one dereference operator. What you're doing here is defining a one-dimensional array that contains the same number of elements as the original two-dimensional array. If your data can be best represented by a matrix, then I recommend you use the first version: intMatrix1[i][j].
The difference is that the first array:
intMatrix1 = (int **)malloc(lines * sizeof(int *));
Creates an array of pointers intMatrix1. Each of those pointers points to an int array (which you malloc here).
for (i = 0; i < lines; ++i)
intMatrix1[i] = (int *)malloc(columns * sizeof(int));
That's why you need the 2 stars (dereference to the pointer array, then to the int array) in the declaration and the double brackets to access single elements:
int **intMatrix1;
int i = intMatrix[row][column];
int i = *(*(intmatrix + row) + column);
For the second matrix, you create just an int array of size column * rows.
int *intMatrix2 = (int *)malloc(lines * columns * sizeof(int));
int i = intMatrix[row + column];
int i = *(intMatrix + row + column);
To print the 2 arrays you will have to use different print functions, because the internal structure of the 2 matrix is different, but you already know the different methods to access both arrays.

Having trouble returning C returning array

I declare hws globally and try to return it in this method but I get a pointer error. I was wondering if anyone knew why that is and could suggest a solution? Randomize just get a random number.
extern int hws[100][20];
int randomize()
{
int value;
int tru_fals = 0;
value = -1;
while ( tru_fals != 1 )
{
value = rand();
if ( 0 < value )
{
if( 101 > value )
{
tru_fals = 1;
}
}
}
return value;
}
int *populate()
{
int i, j;
i = 0;
j = 0;
while( i < 20 )
{
while ( j < 100)
{
int temp = randomize();
hws[i][j] = temp;
j++;
}
i++;
}
return hws;
}
there is a bug: the array is declared as 100x20 but then you iterate through it like it is 20x100.
You define extern int hws[100][20];.
This doesn't create any array. It just says that somewhere in the program, there should be one.
To make it work, some other source file must really define the array - int hws[100][20]; (without extern). Then, if you compile both and link together, it should work.
If you only want one source file, it's much easier - just remove extern.
But: Just noticed Serge's answer, which is actually the real cause of the problem.
Except when it is the operand of the sizeof, _Alignof, or unary & operator, or is a string literal being used to initialize another array in a declaration, an expression of type "N-element array of T" will be converted ("decay") to an expression of type "pointer to T", and its value will be the address of the first element in the array (6.3.2.1/3).
In the line return hws; in populate, the type of the expression hws is "100-element array of 20-element array of int"; by the rule above, it will be converted to type "pointer to 20-element array of int", or int (*)[20]. Thus, the correct declaration for populate would need to be
int (*populate())[20]
{
...
return hws;
}
which reads as
populate -- populate
populate() -- is a function
*populate() -- returning a pointer
(*populate())[20] -- to a 20-element array
int (*populate())[20] -- of int.
and the type of whatever you return the result to would need to be int (*)[20] as well.
Having said that...
Using global variables this way is highly discouraged for a number of reasons. It would be better to pass the array in to populate as a parameter, like so:
void populate(int (*arr)[20], size_t rows)
{
size_t i, j;
for (i = 0; i < rows; i++)
{
for (j = 0; j < 20; j++)
{
arr[i][j] = randomize();
}
}
}
You would call this as simply
populate(hws, sizeof hws / sizeof hws[0]);
If you're using a compiler that supports variable length arrays (either a C99 compiler or a C2011 compiler that does not define __STDC_NO_VLA__ or defines it to 0), you could define the function as
void populate(size_t cols, size_t rows, int (*arr)[cols]) // cols must be declared
{ // before it can be used
size_t i, j; // to declare arr
for (i = 0; i < rows; i++)
{
for (j = 0; j < cols; j++)
{
arr[i][j] = randomize();
}
}
}
and call it as
size_t rows = sizeof hws[0] / sizeof hws[0][0]; // dividing the size of the array
size_t cols = sizeof hws / sizeof hws[0]; // by the size of the first element
populate(cols, rows, hws); // gives the number of elements
so you're not hardcoding the 20 anywhere.
If you aren't using a compiler that supports variable length arrays, and you don't want to hardcode the number of rows in the function prototype, you can do something like this:
void populate(int *arr, size_t rows, size_t cols)
{
size_t i, j;
for (i = 0; i < rows; i++)
{
for (j = 0; j < cols; j++)
{
arr[i * rows + j] = randomize();
}
}
}
and call it as
// rows and cols calculated as above
populate(&hws[0][0], rows, cols);
In this case, instead of passing a pointer to the array, we pass a pointer to the first element (the address value is the same, but the type is int * instead of int (*)[20]. So the populate function treats it like a 1D array, and computes the offset with i * rows + j. Note that this trick will only work for 2D arrays that have been allocated contiguously.
This also means that populate can work with arrays of any size, not just Nx20.
hws is a matrix, it means that its and int **
You are returning and int * so you are having a pointer type mismatch.
First, it doesn't need to be returned since it's global. Second, it is a pointer to a pointer to an int. It's an array of an array.

Getting a subroutine to return three seperate arrays of random numbers in C

I currently have code for a subroutine to return a pointer to an array. This array is a list of random numbers for a one dimensional monte-carlo integral. I am now trying to do a multi dimensional equivalent which requires 3 arrays of random numbers and instead of having a separate subroutine for each I'm trying to make one which returns a 3 by N + 1 array. Could somebody please help me with the coding for this. A mate mentioned I would need a double pointer but most web sources have been unhelpful thus far. Here is my single array code:
double* rdm_Y(void)
{
double* Random_number_list_Y = calloc(N + 1, sizeof(double));
int i;
sleep(1);
srand(time(NULL));
for (i = 1; i <= N; i++) {
Random_number_list_Y[i] = (float) rand() / (float) RAND_MAX;
}
return Random_number_list_Y;
}
Many Thanks!
Jack Medley
The general pattern for dynamically allocating a 2D array of type T (where T can be int, double, etc.) is
#include <stdlib.h>
T **alloc(size_t rows, size_t columns)
{
T **arr = malloc(sizeof *arr, rows); // type of *arr is T *
if (arr)
{
size_t i;
for (i = 0; i < rows; i++)
{
arr[i] = malloc(sizeof *arr[i], columns); // type of *arr[i] is T
if (arr[i])
{
size_t j;
for (j = 0; j < columns; j++)
{
arr[i][j] = initial_value_for_this_element;
}
}
}
}
return arr;
}
Try:
struct res{
double *arr1, *arr2, *arr3;
};
main(){
struct res r;
r.arr1 = rdm_Y();
r.arr2 = rdm_Y();
r.arr3 = rdm_Y();
// in r you have 3 pointers to 3 separate arrays
}
or something like this
The three methods I can think of are:
A *double to a 1D array of size 3xN (you can just pretend it's three arrays)
A **double to an array of three *doubles, each one pointing to an array of N
A struct containing three *doubles, each one pointing to an array of N
If you don't like pretending for method 1 you can declare two more *doubles and set them to the return value + N and + 2N respectively. Also don't forget to free() you should have 1, 4, and 3 free()s to do for each of the methods respectively.

Resources