In the code below, i am taking n as a user input, and depending on its value i have allocated memory to the pointer array (both n and pointer array are a part of a structure). The whole code works well for values of n below 4, anything 4 or beyond, its giving a segmentation fault while inputting values in the pointer array.
I can imagine that it might be because the memory isn't getting allocated but why its only beyond 4 I don't understand
Here is a snippet where the problem is happening.
#include <stdio.h>
#include <stdio_ext.h>
#include <stdlib.h>
// static int n;
typedef struct test_case {
int n;
int *test[];
} testCase;
int maxsc(testCase *test_case_ptr);
int find_maximum(int *ptr, int n);
int main() {
int T;
int x = 0;
int temp;
testCase *test_case_ptr;
printf("T = ");
scanf("%d", &T);
printf("\n");
for (int i = 0; i < T; i++) {
printf("N = ");
scanf("%d", &test_case_ptr->n);
temp = test_case_ptr->n;
printf("\n");
test_case_ptr = (testCase *)malloc(sizeof(struct test_case));
for (int i = 0; i < temp; i++) {
test_case_ptr->test[i] = malloc(sizeof(int *) * test_case_ptr->n);
}
test_case_ptr->n = temp;
// printf("%d\n", test_case_ptr->n);
printf("give values\n");
for (int j = 0; j < test_case_ptr->n; j++) {
for (int k = 0; k < test_case_ptr->n; k++) {
scanf("%d", &test_case_ptr->test[j][k]);
}
}
int max_score = maxsc(test_case_ptr);
printf("\n");
printf("The max_score_%d = %d \n", x++, max_score);
}
}
First, you try to use the test_case_ptr struct before allocating mem for it. Second, when using a flexible array, you need to alloc the mem for it when you malloc the mem for the struct.
scanf("%d", &temp);
// Allocate mem for the struct plus the array
test_case_ptr = malloc(sizeof(struct test_case) + sizeof(int *) * temp);
test_case_ptr->n = temp;
// Allocate each row in the array
for (int i = 0; i < test_case_ptr->n; i++) {
test_case_ptr->test[i] = malloc(sizeof(int) * test_case_ptr->n);
}
// .....
Related
For an assignment I need to make a sorting algorithm for n amount of vector arrays. The assignment specifically tells me to not swap the value of what the pointers are pointing to, but the address that is stored in those pointers. The result will then be printed using those pointers.
My problem is that I can't seem to accomplish the swapping of the addresses that the pointers contain. I have searched SO for related questions but they almost all change the values of where the pointers are referring to.
So far I have this:
Swap function
void swap(double **p, double **q, int i, int j){
double* tmp;
tmp = &p;
*p= &q;
*q = tmp;
printf("\tSwapped [%d][%d] and [%d][%d]\n", i,j, (i-1), j);}
And my main function
int main (void){
int dim, num, *tmp;
int i, j, a;
double **w;
scanf("%d %d", &dim, &num); /* read the dimension and amount of array*/
w = calloc(num, sizeof(double *)); /* allocate array of num pointers */
for (i = 0; i<num; i++)
{
/*allocate space for a dim-dimensional vector */
w[i] = calloc(dim, sizeof(double));
/* read the vector */
for (j = 0; j < dim; j++)
{
scanf("%le", &w[i][j]);
}
}
a = 0;
while (a <= num)
{
/*sort num times*/
i = (num -1);
while(i != 0)
{
if ((argument1) > (argument2) )
{ /*swap each columns of the rows individually*/
printf("\tSwapping..\n");
for(j = 0; j<dim; j++)
{
swap(&w[i][j], &w[i-1][j], i, j);
}
}
i--;
}
a++;
}
for(i=0; i<num; i++)
{
for(j=0; j<dim; j++)
{
printf("%e ",w[i][j]);
}
printf("\n");
}
return 0;
}
When i test this program, it does enter the swap function correctly but the printed result is the same as the input (so not swapped). Can anyone help me why this isn't working?
The swap function can look like
void swap( double **p, double **q )
{
double *tmp = *p;
*p = *q;
*q = tmp;
}
As for the code that is used to sort arrays then it is invalid and does not make sense. At least the variables argument1 and argument2 are not declared.
So I've this:
int main()
{
int workers;
printf("How many workers are there?\n");
scanf("%d", &workers);
printf("What are their preferences?\n");
int *pref = malloc(workers * sizeof(int));
if (pref == NULL)
return -1;
fillPreferences(pref, workers);
return 0;
}
I want now to fill the "pref" 2d array in this function:
void fillPreferences(int pref[][], int size)
{
for (int i=0;i<size;i++)
{
for (int j=0;j<size;j++)
{
scanf(" %d", &pref[i][j]);
}
}
}
It doesn't work, probably because I'm using the pointer wrong. How can I use malloc and then call a function and receive the values in the 2d array by doing pref[i][j]? (Note that I'm not looking to do something like scanf(..., &pref+i) or whatever. I need to actually use that 2d array.
Thanks :)
When you write a[i], it is turned into *(a+i). That is, a[i] accesses the memory by a+i address (well, it is a+i*sizeof(element) even).
As such, a[i][j] means *(*(a+i)+j). Two memory accesses. For this to work, your a should be an array of arrays. That is, you need to malloc its elements first and then malloc a memory to hold them.
In your particular case, i doubt you need it. What you need is make it 1D-array (which is it already) and calculate index from your two indices in whatever fashion you wish.
Your pref array is 1D so you can make it in this way:
#include <stdio.h>
#include <stdlib.h>
void fillPreferences(int **pref, int size)
{
int prefNum=0;
for (int i=0;i<size;i++)
{
puts("Number of preferences");
scanf("%d",&prefNum);
pref[i]=malloc(sizeof(int)*prefNum);
puts("Enter preferences");
for(int j=0;j<prefNum;j++){
scanf(" %d", &pref[i][j]);
}
}
}
int main()
{
int workers;
printf("How many workers are there?\n");
scanf("%d", &workers);
printf("What are their preferences?\n");
int **pref = malloc(workers * sizeof(int *));
if (pref == NULL)
return -1;
fillPreferences(pref, workers);
// Show values
printf("%d %d %d",pref[0][0],pref[1][0],pref[2][0]);
return 0;
}
You allocate memory for a 1D array, but the function you have is designed to accept a 2D array and fill it (although the function definition is incorrect and won't compile).
Corrected code:
#include <stdio.h>
#include <stdlib.h>
void fillPreferences(int** pref, int size)
{
for (int i = 0; i < size; i++)
{
for (int j = 0; j < size; j++)
{
scanf("%d", &pref[i][j]);
}
}
}
int main()
{
int workers;
printf("How many workers are there?\n");
scanf("%d", &workers);
printf("What are their preferences?\n");
int **pref = malloc(workers * sizeof(int*));
if (pref == NULL)
return -1;
for(int i = 0; i < workers; i++)
{
pref[i] = malloc(workers * sizeof(int));
if(pref[i] == NULL)
{
for(int j = 0; j < i; j++)
free(pref[j]);
free(pref);
return -1;
}
fillPreferences(pref, workers);
/* Don't forget to `free` everything after its use! */
return 0;
}
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).
Here's my main:
int main()
{
int i;
int *a = readData(N);
int *f = frequency(a, N, MAX);
int c = 0;
printf("%9s %9s\n", "Number", "Frequency");
for( i = 0; i <= MAX; i ++)
{
c += f[i];
printf("%9d %9d\n", i, f[i]);
}
printf("total frequency for all words: %d\n", c);
free(f);
free(a);
printf("All memory freed!\n");
return(0);
}
and here is the first supporting function
int * readData(int size)
{
int i, *array = malloc(N*sizeof(int));
for(i =0; i<N;i++)
scanf("%d", &array[i]);
return array;
}
and the second supporting function
int * frequency(int *input, int size, int max)
{
int i, x;
int *farray = malloc(max+1*sizeof(int));
for(i = 0; i<=max;i++)
farray[i]=0;
for(i = 0; i<1099; i++)
{
x = input[i];
farray[x]++;
}
return farray;
}
Everything works great! When I run it through valgrind, it tells me that all my memory was freed. But, when I run the program normally, it crashes at the end with a core dump when I free the allocated memory. Why? Thanks in advance! I'm new at C.
It's true that all the memory is freed, but the size you allocated is not correct.
int *farray = malloc(max+1*sizeof(int));
Here, the size is max plus one sizeof(int)), it should be:
int *farray = malloc((max+1)*sizeof(int));
void load(int *n, int *x, int **arr)
{
arr = (int**)malloc(sizeof(int*)*(*n));
for(int i = *n; i >= 0; i--)
{
scanf("%d", &arr[i]);
}
}
int main()
{
int n = 0, x = 0;
int *arr;
load(&n, &x, &arr);
printf("%d", arr[1]);
return EXIT_SUCCESS;
}
The program compiles properly, but it throws windows error during the printf() in main function. Displaying just "arr" gives random big numbers. What is wrong here?
arr = (int**)malloc(sizeof(int*)*(*n));
doesn't change anything in main, it only overwrites the copy of the pointer (address of arr in main) that load receives.
What the function should do is change arr in main, for that, you have to dereference the argument,
*arr = (int*)malloc(sizeof(int)*(*n)); // cast for C++ compiler left in
to change the value of arr in main. (The object that the argument arr of load points to, that is arr in main, needs to be changed, hence you need to modify *arr in load.)
The scans should then be
scanf("%d", &(*arr)[i]);
or (equivalent)
scanf("%d", *arr + i);
#include <stdio.h>
#include <stdlib.h>
void load(int *n, int *x, int **arr)
{
int i = 0;
*arr = (int*) malloc(*n * sizeof(int));
if(!*arr) {
perror("Can not allocate memory!");
return;
}
for(i = *n; i >= 0; i--)
{
scanf("%d", *arr + i);
}
return;
}
int main()
{
int n = 0, x = 0;
int *arr;
int i;
/* You probably need to initialize n */
n = 5;
load(&n, &x, &arr);
for(i = n; i >= 0; i--)
{
printf("%d - %d\n", i, arr[i]);
}
return EXIT_SUCCESS;
}