receive 2d pointer array in the calling function - c

I am trying to receive a 2D pointer array in the calling function.
I called a function subsets from the main function, the subset function will be returning a 2D pointer array
int **subsets(int *A, int n1, int *len1)
{
int **arr;
num = pow(2, n1);
*len1 = num;
arr = (int **) malloc(num * sizeof(int *));
for (i = 0; i < num; i++)
{
arr[i] = (int *)malloc(sizeof(int));
}
return arr;
}
In this function I am declaring a 2D array dynamically int **arr and then trying to receive this return array in the main function. Note than in *len1 I am assigning the rows value the 2D array and the column values of the 2D array will be different bases on the subsets, like for a given array[1,2,3] it will be like this:
[
[],
[1],
[1, 2],
[1, 2, 3],
[1, 3],
[2],
[2, 3],
[3],
]
I am basically doing the subset problem, but not able to receive the 2D return array in the main function, can somebody please tell me how to receive this 2D pointer array in a calling function.
Appreciate the response..:)
[update from comment:]
This is how I tried to call to it from main function, but it's wrong:
int **res = subsets(A, n1, &len1);
int i = 0, j = 0;
for(i = 0; i < len1; i++)
{
for(j = 0; j < n1; j++)
{
printf("%d", res[i][j]);
}
printf("\n");
}
As n1 (column) value will be different for each row.

I'm not quite sure what you want to achieve, but I suppose the following code may help you:
#include <stdio.h>
#include <stdlib.h>
int **subsets(int A);
int main(void)
{
int **arr = subsets(3);
int i, j;
for(i = 0; i < 1 << 3; i++)
{
for(j = 0; arr[i][j]; j++)
{
printf("%d", arr[i][j]);
}
putchar('\n');
}
}
int **subsets(int A)
{
int **arr = malloc(sizeof (int *) * (1 << A));
int i;
for(i = 0; i < 1 << A; i++)
{
arr[i] = malloc(sizeof (int) * A); // Can be smaller
int *ptr = arr[i];
int j;
for(j = 0; j < A; j++)
{
if(i & (1 << j))
{
*ptr++ = j + 1;
}
}
*ptr = 0;
}
return arr;
}
Purely for brevity, things like checking the return value of malloc() are omitted. Don't forget to add them.

Related

How to pass and return two-dimensional array from function in c

I am relatively new to c, and I still have not been able to find a good way of passing and returning a multi-dimensional array from a function. I found the following code, however it doesn't seem like a good way to do things because it passes the array and then to use it, it creates a duplicate with the malloc function. Is there a way to do it without the copying and malloc function, or a better way to pass and return an 2d array from a function in c in general? Thanks.
#include <stdio.h>
#include <stdlib.h>
int **matrix_sum(int matrix1[][3], int matrix2[][3]){
int i, j;
int **matrix3;
matrix3 = malloc(sizeof(int*) * 3);
for(i = 0; i < 3; i++) {
matrix3[i] = malloc(sizeof(int*) * 3);
}
for(i = 0; i < 3; i++){
for(j = 0; j < 3; j++){
matrix3[i][j] = matrix1[i][j] + matrix2[i][j];
}
}
return matrix3;
}
int main(){
int x[3][3], y[3][3];
int **a;
int i,j;
printf("Enter the matrix1: \n");
for(i = 0; i < 3; i++){
for(j = 0; j < 3; j++){
scanf("%d",&x[i][j]);
}
}
printf("Enter the matrix2: \n");
for(i = 0; i < 3; i++){
for(j = 0; j < 3; j++){
scanf("%d",&y[i][j]);
}
}
a = matrix_sum(x,y); //asigning
printf("The sum of the matrix is: \n");
for(i = 0; i < 3; i++){
for(j = 0; j < 3; j++){
printf("%d",a[i][j]);
printf("\t");
}
printf("\n");
}
//free the memory
for(i = 0; i < 3; i++) {
free(a[i]);
}
free(a);
return 0;
}
The array are not copied for agurments. Just pointers to the first elements of them (int[3]) are passed.
To avoid malloc(), you should add another argument to specify the array where the result should be stored.
#include <stdio.h>
void matrix_sum(int matrix3[][3], int matrix1[][3], int matrix2[][3]){
int i, j;
for(i = 0; i < 3; i++){
for(j = 0; j < 3; j++){
matrix3[i][j] = matrix1[i][j] + matrix2[i][j];
}
}
}
int main(){
int x[3][3], y[3][3], a[3][3];
int i,j;
printf("Enter the matrix1: \n");
for(i = 0; i < 3; i++){
for(j = 0; j < 3; j++){
scanf("%d",&x[i][j]);
}
}
printf("Enter the matrix2: \n");
for(i = 0; i < 3; i++){
for(j = 0; j < 3; j++){
scanf("%d",&y[i][j]);
}
}
matrix_sum(a,x,y);
printf("The sum of the matrix is: \n");
for(i = 0; i < 3; i++){
for(j = 0; j < 3; j++){
printf("%d",a[i][j]);
printf("\t");
}
printf("\n");
}
return 0;
}
An array can be declared and used through a reference (pointer)
for instance
char array[] = {'h','e','l', 'l', 'o', '\0'};
char *pointer = array;
the way pointers work can be understood by calling sizeof() on a given type
printf("char:%d\nchar_pointer: %d\n", sizeof(char), sizeof(char*));
which results in the following output.
char:1
char_pointer: 4
these results mean that even though a char has 1byte, its pointer needs 4 in order to be stored in memory thus, they are not the same type.
now in order to pass an array as an argument to a function you have many options
void function1(array[4])
{
//this function can receive an array of four elements and only four elements;
//these types of functions are useful if the algorithm inside the function only works
//with a given size. e.g. matrix multiplication
}
//or
void function2(char array[], int size)
{
//this function can receive an array of elements of unknown size, but you can
//circumvent this by also giving the second argument, the size.
int i;
for(i = 0; i <= size; i++)
{
printf("%c", array[i]);
}
}
In order to use or call any of these functions you could pass the array or a pointer to the array
function2(array, 5);
function2(pointer, 5);
//these results are the same
The same applies to a multidimensional array
void function3(char** multi_dim_array, array_size_first_dim, array_size_second_dim);
//and you can call it by using the same syntax as before;
void main(int argc, char[] argv*)
{
char** multi_dim = malloc(sizeof(char*) * 3);
int i;
for(i = 0; i<=3 ; i++)
{
multi_dim[i] = malloc(sizeof(char) * 4);
}
function3(multi_dim, 3,4);
}
if you want to return a multidimensional array you can just return a pointer
char **malloc_2d_array(int dim1, int dim2)
{
char ** array = malloc(sizeof(char*)*dim1);
int i;
for(i = 0; i<=dim2; i++)
{
array[i] = malloc(sizeof(char) * dim2);
}
return array;
}
as a final note, the reason the code you found, copies the array, is because of functional programming(a way of programming if you will) where a function call cant modify its input, thus it will always create a new value;
First of all this is not gonna be a technical explanation. I am just gonna try and explain what works not why.
For passing a multidimensional array you can use either an array with a defined size as you did in your example code:
void matrix_sum(int matrix3[][3])
Or if you don't want to use a defined size and want to take care of memory usage you can use a pointer to a pointer. For this case you also need to pass the size (unless you are passing NULL-terminated strings). Like this:
void matrix_sum(int **matrix, int size)
BUT for this case you can't call the function with a "normal" array. You need to use a pointer to a pointer or a pointer to an array.
int **matrix;
// make sure to allocate enough memory for this before initializing.
or:
int *matrix[];
For returning an array you can just return a pointer to a pointer like you did in your code example.
But you don't need to return an array, because if you change a value in an array, (in a different function) the value will stay changed in every other function.
A short example for this:
#include <stdio.h>
void put_zeros(int matrix[][3])
{
int i;
int j;
i = 0;
while (i < 3)
{
j = 0;
while (j < 3)
{
matrix[i][j] = 0;
j++;
}
i++;
}
}
void print_matrix(int matrix[][3])
{
int i;
int j;
i = 0;
while (i < 3)
{
j = 0;
while (j < 3)
{
printf("%d ", matrix[i][j]);
j++;
}
printf("\n");
i++;
}
}
int main(void)
{
int matrix_first[3][3] = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
print_matrix(matrix_first);
put_zeros(matrix_first);
print_matrix(matrix_first);
}
This will print "1 2 3 4 5 6 7 8 9" because that's the first value we assigned.
After calling put_zeros it will contain and print "0 0 0 0 0 0 0 0 0" without the put_zeros returning the array.
1 2 3
4 5 6
7 8 9
0 0 0
0 0 0
0 0 0

C Language, dynamic 3d array

I have to create a dynamic and 3 dimensional integer-Array in C.
But I have to create the pointers separately and use malloc. I know how to create 2d Array with malloc but I get confused using the following method, and i couldn't really find other question similar to this.
2x2x2 Integer-Array
First step:
int *firstD;
firstD = (int) malloc(2*sizeof(int));
Second step:
int *secondD;
secondD = (int) malloc(2 * firstD * sizeof(int));
Third step:
int *thirdD;
thirdD = (int) malloc(2 * secondD * sizeof(int));
I think maybe I have to add pointers in the starting (int*) and increase it every stepp by one more pointer?
Allocate an array to store pointers to arrays of row pointers.
Allocate arrays to store row pointers.
Allocate arrays to store each rows.
#include <stdlib.h>
int main(void) {
int size1 = 2, size2 = 2, size3 = 2;
int*** array;
array = malloc(sizeof(int**) * size1); // 1
for (int i = 0; i < size1; i++) {
array[i] = malloc(sizeof(int*) * size2); // 2
for (int j = 0; j < size2; j++) {
array[i][j] = malloc(sizeof(int) * size3); // 3
}
}
// free arrays
for (int i = 0; i < size1; i++) {
for (int j = 0; j < size2; j++) {
free(array[i][j]);
}
free(array[i]);
}
free(array);
return 0;
}
I wrote type names explicitly in the above example, but I suggest using dereferencing to obtain size of elements to allocate is better to prevent causing typos.
#include <stdlib.h>
int main(void) {
int size1 = 2, size2 = 2, size3 = 2;
int*** array;
// allocate arrays
array = malloc(sizeof(*array) * size1); // 1
for (int i = 0; i < size1; i++) {
array[i] = malloc(sizeof(*array[i]) * size2); // 2
for (int j = 0; j < size2; j++) {
array[i][j] = malloc(sizeof(*array[i][j]) * size3); // 3
}
}
// free arrays
for (int i = 0; i < size1; i++) {
for (int j = 0; j < size2; j++) {
free(array[i][j]);
}
free(array[i]);
}
free(array);
return 0;
}
Onitted in the above examples to make them simple, but you should check results of malloc() to see if the allocations are successful.

How to send array as pointer to function C

I am trying to make a code where i send an array from a function to be erased, i do not know the length of the array, since it will be declared after a variable that will be typed by the user, so im trying to send as a pointer. but i constantly get an error. the code looks like this
int apagaarray(int *array,int l,int c){
for(int i=0;i<l;i++){
for(int j=0;j<c;j++){
array[i][j]=0;
}
}
}
but it returns an error:
error: subscripted value is neither array nor pointer nor vector|
what is going on ? is there a way to send an array to a function without having the parameters ?
i think it would be the most correct this way:
int func(int **array, int l, int c)
{
for (int i = 0; i < l; i++) {
for (int j = 0; j < c; j++) {
array[i][j] = 0;
}
}
}
int main(void)
{
int l = 5, c = 5;
int **array = malloc(sizeof(int *) * l);
for (int i = 0; i < l; i++) {
array[i] = malloc(sizeof(int) * c);
for (int j = 0; j < c; j++) {
array[i][j] = j+1;
}
}
//print something
printf("%d\n", array[3][3]);
//empty it
// make note that im passing **array <= a ptr of ptr
func(array, l, c);
return 0;
}
not my usual self to provide a code but please try to run through it and see if that answers
Matrices should be represented as follows:
Either int **array or int *array[]
The correct function is:
int apagaarray(int **array,int l,int c){
for(int i=0;i<l;i++){
for(int j=0;j<c;j++){
array[i][j]=0;
}
}
}
#include <stdio.h>
void printArray(int *arr, int rows, int cols) {
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
// Use address to refer the array element.
printf("%d ", *(arr + (i * cols) + j));
}
printf("\n");
}
}
void eraseArray(int *arr, int rows, int cols) {
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
// Use address to refer the array element.
*(arr + (i * cols) + j) = 0;
}
}
}
int main()
{
int arr[3][3] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
printArray((int *)arr, 3, 3); // Cast array to 1-dim array
eraseArray((int *)arr, 3, 3); // Cast array to 1-dim array
printArray((int *)arr, 3, 3); // Cast array to 1-dim array
return 0;
}
Cast the array to one-dimensional array and pass it.
You can change the value too, Since you are passing pointers instead of values.

Understanding Array of pointers

I am doing something like this;
int main()
{
int *b[2], j;
for (j = 0; j < 2; j++)
{
b[j] = (int *)malloc(12 * sizeof(int));
}
return 0;
}
Please tell me what this instruction really means? And how can I pass this array of pointers to a function to access values like *(B[0]+1),*(B[1]+1) etc?
int main(void)
{
int *b[2], j; // initialization of an array of pointers to integers (size = 2)
for (j = 0; j < 2; j++) // for each of the pointers
{
b[j] = malloc(12 * sizeof (int)); // allocate some space = 12 times size of integer in bytes (usually 4)
}
return 0;
}
If you want to pass this array to a function you can just pass b
foo(b);

Array of type int doesn't get modified from the function call [duplicate]

This question already has answers here:
Finding length of array inside a function [duplicate]
(7 answers)
Closed 5 years ago.
For some reason that I'm not aware of, array from main() doesn't get to be modified when it should. Isn't "a" passed by reference? Can someone please guide me a little bit?
Here is the code:
#include "stdio.h"
void sort(int list[])
{
//int list[] = { 4, 3, 2, 1, 10 };
int n = sizeof(list) / sizeof(int);
int min = 0;
int temp = 0;
for (int i = 0; i < n; i++)
{
min = i;
//profiler.countOperation("compSort", n, 1);
for (int j = i + 1; j < n; j++)
{
if (list[j] < list[min])
{
min = j;
//profiler.countOperation("compSort", n, 1);
}
}
if (min != i)
{
//profiler.countOperation("compSort", n, 1);
temp = list[min];
list[min] = list[i];
list[i] = temp;
}
}
}
int main()
{
int a[5] = {4, 3, 2, 1, 10};
sort(a);
printf("%d\n", a[0]);
for (int i = 0; i < 5; i++)
{
printf("%d", a[i]);
}
return 0;
/*int arr[MAX_SIZE];
for(int t = 0; t < 1; t++)
{
for (int n = 100; n < 3000; n = n + 300)
{
FillRandomArray(arr, n);
sort();
printf("done %d \n", n);
if (!IsSorted(arr, n)
{
printf("error sort \n");
}
}
}
profiler.addSeries("TotalSort", "cmpSel", "atribSel");
profiler.createGroup("SortMediu", "TotalSort", "cmpSel", "atribSel");
profiler.showReport();*/
}
The problem is with
int n = sizeof(list) / sizeof(int);
arrays, once passed as function arguments decays to the pointer to the first element. They don't have array properties anymore. So, the list here is adjusted as a pointer to int.
Quoting C11, chapter §6.7.6.3
A declaration of a parameter as ‘‘array of type’’ shall be adjusted to ‘‘qualified pointer to
type’’, where the type qualifiers (if any) are those specified within the [ and ] of the
array type derivation.
Solution: You need to calculate the size at the caller (before the array decay happens) and pass that as a different argument to the called function.
Array passed to function in that way decays to pointer so
int n = sizeof(list) / sizeof(int);
Result in sizeof(int *)/sizeof(int)
You can use VLAs to sole the problem
#include "stdio.h"
void sort(size_t n, int list[n])
{
size_t min = 0;
int temp = 0;
for (size_t i = 0; i < n; i++)
{
min = i;
//profiler.countOperation("compSort", n, 1);
for (size_t j = i + 1; j < n; j++)
{
if (list[j] < list[min])
{
min = j;
//profiler.countOperation("compSort", n, 1);
}
}
if (min != i)
{
//profiler.countOperation("compSort", n, 1);
temp = list[min];
list[min] = list[i];
list[i] = temp;
}
}
}
int main(void)
{
int a[5] = { 4, 3, 2, 1, 10 };
sort(sizeof(a) / sizeof(a[0]), a);
printf("%d\n", a[0]);
for (int i = 0; i < 5; i++)
{
printf("%d", a[i]);
}
printf("\n");
return 0;
}

Resources