Reputation: 1063
I need to write a function that returns an array of arrays:
return_array = { {1}, {1,2,3}, {...}, ....};
Each array has a different size. The function must comply to following signature:
int** generate(int n, int** column_sizes)
n
is the input to function and I use that to create the return-array
.
I know how to create return_array
, but I don't understand how size of each array should be returned in double pointer int** column_sizes
?
I would just returned them in a single pointer int* column_sizes
like below:
int** generate(int n, int* column_sizes){
int return_size=some_function(n);
int** returned_array=malloc(return_size*sizeof(int*));
...
column_sizes[0]=c0; // First array size
column_sizes[1]=c1; // Second array size
...
return returned_array;
}
Upvotes: 0
Views: 1588
Reputation: 827
The purpose of the column_sizes
parameter is to pass the number of elements in each of the sub-arrays of the returned double-pointer to the caller.
If it is to be allocated inside your function, it has to be a double pointer.
#include <stdlib.h>
#include <stdio.h>
int** generate(int n, int** column_sizes){
*column_sizes = malloc(n*sizeof(int));
for (int i=0; i<n; i++)
(*column_sizes)[i]=i;
int** return_array=malloc(n*sizeof(*int));
for(int i=0; i<n; i++) {
return_array[i]=malloc((*column_sizes)[i]*sizeof(int));
for(int j=0; j<(*column_sizes)[i]; j++) {
// set the j'th value in the i'th array
return_array[i][j]=i*j;
}
}
return return_array;
}
int main() {
int *column_sizes;
int n=4;
int** arrays= generate(n, &column_sizes);
printf("%i\n", *column_sizes);
for(int i=0; i<n; i++) {
for(int j=0; j<column_sizes[i]; j++) {
printf("%i %i: %i\n",i,j, arrays[i][j]);
}
}
}
Upvotes: 3
Reputation: 222352
There are some unresolved issues in the question, notably:
Nonetheless, we can start answering. It looks like you need to allocate at least three spaces: One for the column sizes, one for the pointers to the columns, and one for all the actual int
data. This supposes we put all the int
data for all the columns in a single array but point into appropriate places in the array through the column pointers. An alternative is to allocate space for each column’s data separately.
In the former case, the function could be:
int **generate(int n, int **column_sizes)
{
// Allocate space for columns sizes and assign column sizes.
int NumberOfColumns = /* Some calculation not explained in question. */;
// (size_t would be better than int, but I will use the types in the question.)
int *sizes = malloc(NumberOfColumns * sizeof *sizes);
// Insert code to abort if malloc failed.
*column_sizes = sizes;
int TotalElements = 0;
for (int i = 0; i < NumberOfColumns; ++i)
{
sizes[i] = /* Some calculation to find size of column i. */;
TotalElements += sizes[i];
}
// Allocate space for pointers to columns.
int **returned_array = malloc(NumberOfColumns * sizeof *returned_array);
// Insert code to abort if malloc failed.
// Allocate space for the actual int data.
int *Space = malloc(TotalElements * sizeof *Space);
// Insert code to abort if malloc failed.
// Assign pointers to columns.
returned_array[0] = Space;
for (int i = 1; i < NumberOfColumns; ++i)
returned_array[i] = returned_array[i-1] + sizes[i-1];
// Fill in the actual int data.
for (int i = 0; i < NumberOfColumns; ++i)
for (int j = 0; j < column_sizes[i]; ++j)
returned_array[i][j] = /* Some unexplained calculation. */;
return returned_array;
}
With this definition, the caller could free the memory by freeing the array of column sizes, freeing the space pointed to by the first pointer in the returned array, and freeing the returned array. If, in an alternative implementation, each column is allocated separately, the caller would have to free each pointer in the returned array.
Upvotes: 1