Function pointer in argument in C - c

I have to do an exercise where I have a certain numbers of functions and every function do a different thing like sort all the negative numbers from the array.
Moreover I have to create a function display with 3 argument pointers to an array, size of it and a name of a function which receives int and that the issue is int (Function pointer). I try to do this but this don't work and I don't know what to do in order to do correctly this exercise with a function pointer, because I don't understand that.
This is my code
int main (int argc, char **argv)
{
srand (time (NULL));
int arr[MAX_SIZE], second_arr[MAX_SIZE], i;
random_arr (arr);
display (arr, 20, negative_number (arr, second_arr));
system ("PAUSE");
return 0;
}
void random_arr (int *my_arr)
{
int i;
for (i = 0; i < MAX_SIZE; i++) {
*(my_arr + i) = i - 10;
}
}
int negative_number (int *arr, int *sort_arr)
{
int i;
for (i = 0; i < 20; i++) {
if (arr[i] < 0) {
sort_arr[i] = arr[i];
}
}
return sort_arr;
}
void diplay (int *arr, int size, int (*a_function) (int, int))
{
int i = 0;
for (i = 0; i < size; i++) {
printf ("%d\n", a_function);
}
}

It might be different from your intentions because your intentions is not clear.
but I think this would be helpful
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define MAX_SIZE 20
void random_arr (int size, int *my_arr);
int negative_number (int size, int *arr, int *sort_arr);
void display (int *arr, int size, int (*filter_function) (int in_size, int *in_array, int *out_array));
int main (void){
int arr[MAX_SIZE], second_arr[MAX_SIZE], i;
srand(time(NULL));
random_arr(MAX_SIZE, arr);
for(i = 0; i < MAX_SIZE; ++i)
printf("%d ", arr[i]);
puts("");
display (arr, MAX_SIZE, negative_number);
system ("PAUSE");
return 0;
}
void random_arr (int size, int *my_arr){
int i;
for (i = 0; i < size; i++) {
my_arr[i] = rand()%MAX_SIZE - MAX_SIZE/2;
}
}
int negative_number (int size, int *arr, int *sort_arr){
int i, j = 0;
for (i = 0; i < size; i++) {
if (arr[i] < 0) {
sort_arr[j++] = arr[i];
}
}
return j;//new array size
}
void display (int *arr, int size, int (*filter)(int in_size, int *in_array, int *out_array)){
int i = 0;
int *out = malloc(size * sizeof(*out));
int out_size = filter(size, arr, out);
for (i = 0; i < out_size; i++) {
printf ("%d\n", out[i]);
}
free(out);
}

Related

How to create and return dynamic array with function parameters

I have a problem returning dynamic array pointer with function parameter. I get segfault
#include <stdio.h>
#include <stdlib.h>
void createArray(int *ptr, int n)
{
ptr = malloc(n * sizeof(int));
for(int i = 1; i <= n; ++i)
{
*(ptr + (i - 1)) = i*i;
}
}
int main() {
int *array = NULL;
int n = 5;
createArray(array, n);
for(int i = 0; i < n; ++i)
{
printf("%d", array[i]);
}
return 0;
}
I have to fill my array with i*i, when I is from 1 to n.
I don't get any errors or warnings. Just message about segmentation fault. Process finished with exit code 139 (interrupted by signal 11: SIGSEGV)
Memory must be allocate in the calling function, but not in called.
This variant works:
#include <stdio.h>
#include <stdlib.h>
void createArray(int *ptr, int n){
int i;
for(i = 1; i <= n; i++) {
*(ptr + (i - 1)) = i*i;
// fprintf(stdout,"%d %d\n", i, *(ptr + (i -1)));fflush(stdout);
}
}
int main() {
int i, n, *array = NULL;
void *pvc;
n = 5;
array = (int *)malloc(n * sizeof(int));
createArray(array, n);
for(i = 0; i < n; i++) {
fprintf(stdout,"%d %d\n", i, array[i]);fflush(stdout);
}
pvc = (void *)array;
free(pvc);
return 0;
}
You can change pointer through function parameters like this:
void createArray(int **ptr, int n)
{
*ptr = malloc(n * sizeof(int));
for(int i = 1; i <= n; ++i)
{
(*ptr)[i - 1] = i*i;
}
}
int main() {
int *array = NULL;
int n = 5;
createArray(&array, n);
Remember to call function like this: createArray(&array, n);

C array vs pointer in these examples

This question doesn't require any initial explanation, other that to show the examples.
Why does this work (prints the contents of array a):
#include <stdio.h>
int a[100];
void check(int **b)
{
int i;
for (i = 0; i < 100; i++)
printf("%d ", b[0][i]);
}
int main()
{
int *arr = a;
int i;
for (i = 0; i < 100; i++)
{
a[i] = i;
}
check(&arr);
return 0;
}
and this doesn't (compiles with onlinegdb c compiler, but prints nothing)?
#include <stdio.h>
int a[100];
void check(int **c)
{
int i;
for (i = 0; i < 100; i++)
printf("%d ", c[0][i]);
}
int main()
{
int i;
for (i = 0; i < 100; i++)
{
a[i] = i;
}
check((int**)&a);
return 0;
}
I understand that array is a special data type in C, but shouldn't casting it to a pointer type or assigning it to one be the same? Is there a way to make the second example work without the additional pointer?

getting weird output from 2 d array in C

I want to a fill a small 2 d array with arbitrary values before moving onto a bigger array. However, when I compile and run my program, I get some weird output. It is not perfectly square. if someone could point out what im doing wrong that would be great.
void startarray(char (*arr)[10], int y_length, int x_length);
void printarray(char (*arr)[10], int y_length);
int main()
{
char arr[10][10];
startarray(arr, 10,10);
printarray(arr, 10);
return 0;
}
void startarray(char (*arr)[10], int y_length, int x_length)
{
int i;
int j;
for(i = 0; i <= y_length; i++)
{
for(j = 0; j < x_length; j++)
{
arr[i][j] = 'a';
}//end for
arr[i][j] = '\0';
}//end for
}
void printarray(char (*arr)[10], int y_length)
{
int i = 0;
while(i < y_length)
{
printf("\n%s", arr[i]);
i++;
}//end while
}

c- Allocate and Free 2D Array

I am trying to write 2 functions, one to Dynamic allocation a 2D array,Other to free this 2D array:
int allocate(int **array, unsigned int rows, unsigned int columns){
int i;
for (i = 0; i < rows; i++) {
array[i] = malloc(columns * sizeof (int));
}
/* Code fo fill the array*/
return 1;
}
void de_allocate(int **v, unsigned int rows) {
int i;
for (i = 0; i < rows; i++) {
free(v[i]);
}
free(v);
}
int main(int argc, char **argv) {
int rows, columns;
rows = atoi(argv[1]);
columns = atoi(argv[2]);
int *ipp[rows];
allocate(ipp, rows, columns);
de_allocate(ipp,rows);
return 0;
}
I must respect the allocate function signature :
int allocate(int **array, unsigned int rows, unsigned int columns)
And at the end of allocate function ipp must have access to allocated 2D array.
Allocate function it's right but in de_allocate function i have a SIGABRT Signal
The problem is that you are trying to free a stack allocated var with code free(v);
You could do that if you mallocated the array of pointer, but you declare it locally in main function with int *ipp[rows];
Change it to int **ipp = malloc(sizeof(int*)*rows); if you want to leave de_allocate as is.
You could test it with
#include <stdio.h>
#include <stdlib.h>
int allocate(int **array, unsigned int rows, unsigned int columns){
int i;
for (i = 0; i < rows; i++)
{
array[i] = malloc(columns * sizeof (int));
}
/* Code fo fill the array*/
return 1;
}
void de_allocate(int **v, unsigned int rows) {
int i;
for (i = 0; i < rows; i++)
{
free(v[i]);
}
free(v);
}
int main(int argc, char **argv)
{
int rows, columns;
int temp = 0;
rows = atoi(argv[1]);
columns = atoi(argv[2]);
int **ipp = malloc(sizeof(int*)*rows);
allocate(ipp, rows, columns);
for (int i=0; i<rows; i++)
for (int j=0; j<columns; j++)
ipp[i][j] = temp++;
for (int i=0; i<rows; i++)
for (int j=0; j<columns; j++)
printf("ipp[%d][%d] = %d\n", i, j, ipp[i][j]);
de_allocate(ipp,rows);
return 0;
}
void de_allocate(int **v, unsigned int rows) {
int i;
for (i = 0; i < rows; i++) {
free(v[i]);
}
free(v);
-----^----
here you are attempting to free a variable for which you didn't dynamically allocate memory in the first place
}

crash on trying to reallocate a pointer using pointer to this pointer

I have a pointer to a pointer ("paths") and I want to reallocate each pointer (each "path"). But I get a crash. Generally I am trying to find all possible powers of a number, which one can compute for some amount of operations (e.g for two operations we can get power of three and four (one operation for square of a number, then another one either for power of three or four)). I figured out how to do it on paper, now I am trying to implement it in code. Here is my try:
#include <stdio.h>
#include <stdlib.h>
void print_path(const int *path, int path_length);
int main(void)
{
fputs("Enter number of operations? ", stdout);
int operations;
scanf("%i", &operations);
int **paths, *path, npaths, npath;
npaths = npath = 2;
path = (int*)malloc(npath * sizeof(int));
paths = (int**)malloc(npaths * sizeof(path));
int i;
for (i = 0; i < npaths; ++i) // paths initialization
{
int j;
for (j = 0; j < npath; ++j)
paths[i][j] = j+1;
}
for (i = 0; i < npaths; ++i) // prints the paths, all of them are displayed correctly
print_path(paths[i], npath);
for (i = 1; i < operations; ++i)
{
int j;
for (j = 0; j < npaths; ++j) // here I am trying to do it
{
puts("trying to reallocate");
int *ptemp = (int*)realloc(paths[j], (npath + 1) * sizeof(int));
puts("reallocated"); // tried to write paths[j] = (int*)realloc...
paths[j] = ptemp; // then tried to make it with temp pointer
}
puts("memory reallocated");
++npath;
npaths *= npath; // not sure about the end of the loop
paths = (int**)realloc(paths, npaths * sizeof(path));
for (j = 0; j < npaths; ++j)
paths[j][npath-1] = paths[j][npath-2] + paths[j][j];
for (j = 0; j < npaths; ++j)
print_path(paths[j], npath);
puts("\n");
}
int c;
puts("Enter e to continue");
while ((c = getchar()) != 'e');
return 0;
}
void print_path(const int *p, int pl)
{
int i;
for (i = 0; i < pl; ++i)
printf(" A^%i -> ", p[i]);
puts(" over");
}
I am not sure the problem resides with the call to realloc(), rather you are attempting to write to locations for which you have not created space...
Although you create memory for the pointers, no space is created (allocate memory) for the actual storage locations.
Here is an example of a function to allocate memory for a 2D array of int:
int ** Create2D(int **arr, int cols, int rows)
{
int space = cols*rows;
int y;
arr = calloc(space, sizeof(int));
for(y=0;y<cols;y++)
{
arr[y] = calloc(rows, sizeof(int));
}
return arr;
}
void free2DInt(int **arr, int cols)
{
int i;
for(i=0;i<cols; i++)
if(arr[i]) free(arr[i]);
free(arr);
}
Use example:
#include <ansi_c.h>
int main(void)
{
int **array=0, i, j;
array = Create2D(array, 5, 4);
for(i=0;i<5;i++)
for(j=0;j<4;j++)
array[i][j]=i*j; //example values for illustration
free2DInt(array, 5);
return 0;
}
Another point here is that it is rarely a good idea to cast the return of [m][c][re]alloc() functions
EDIT
This illustration shows my run of your code, just as you have presented it:
At the time of error, i==0 & j==0. The pointer at location paths[0][0] is uninitialized.
EDIT 2
To reallocate a 2 dimension array of int, you could use something like:
int ** Realloc2D(int **arr, int cols, int rows)
{
int space = cols*rows;
int y;
arr = realloc(arr, space*sizeof(int));
for(y=0;y<cols;y++)
{
arr[y] = calloc(rows, sizeof(int));
}
return arr;
}
And here is a test function demonstrating how it works:
#include <stdio.h>
#include <stdlib.h>
int ** Create2D(int **arr, int cols, int rows);
void free2DInt(int **arr, int cols);
int ** Realloc2D(int **arr, int cols, int rows);
int main(void)
{
int **paths = {0};
int i, j;
int col = 5;
int row = 8;
paths = Create2D(paths, col, row);
for(i=0;i<5;i++)
{
for(j=0;j<8;j++)
{
paths[i][j]=i*j;
}
}
j=0;
for(i=0;i<5;i++)
{
for(j=0;j<8;j++)
{
printf("%d ", paths[i][j]);
}
printf("\n");
}
//reallocation:
col = 20;
row = 25;
paths = Realloc2D(paths, col, row);
for(i=0;i<20;i++)
{
for(j=0;j<25;j++)
{
paths[i][j]=i*j;
}
}
j=0;
for(i=0;i<20;i++)
{
for(j=0;j<25;j++)
{
printf("%d ", paths[i][j]);
}
printf("\n");
}
free2DInt(paths, col);
getchar();
return 0;
}
The realloc() does not fail. What fails is that you haven't allocated memory for the new pointers between paths[previous_npaths] and paths[new_npaths-1], before writing to these arrays in the loop for (j = 0; j < npaths; ++j).

Resources