This question already has answers here:
How do I work with dynamic multi-dimensional arrays in C?
(9 answers)
Closed 8 years ago.
This is my code. My purpose is to allocate memory to a 2D array at run time upto whatever size is given in input.
Why is segmentation fault occuring? Is it because array elements have to be stored consecutively and malloc(dynamic allocation) is not letting this happen?
OR I am doing some error in writing this code. Please guide me through.
Thanks in advance.
int main(){
// STEP 1
int size,**arr,i=0,j=0;
printf("Enter the size of matrix : ");
scanf("%d",&size);
// STEP 2
arr = (int**)malloc(size*size*sizeof(int));
printf("\n Enter the %d elements : \n",size*size);
for(i=0;i<size;i++){
for(j=0;j<size;j++){
// STEP 3
scanf("%d",&arr[i][j]);
}
}
/*
for(i=0;i<size;i++){
for(j=0;j<size;j++){
printf("%d\n",matrix[i][j]);
}
}
*/
return 0;
}
This is a classic mistake.
A pointer to pointers is actually not the same as a two-dimensional array.
Granted, you can access elements of both via the var[x][y] syntax, but the memory layout of
int foo[x][y]
is different from
int **bar
If you really want to have this dynamic, you will have to allocate space for your list of pointers, then allocate space for your elements to each pointer in turn.
bar = malloc( x * sizeof(int*) );
for ( int i = 0 ; i < x ; i++ )
bar[i] = malloc( y * sizeof(int) );
If at all possible, you should try and avoid this in favor of an actual two-dimensional array, which as of C99 you can declare on the stack even if its size is determined at runtime:
int main()
{
int n;
scanf("%d", &n);
int array[n][n];
// ...
return 0;
}
You should allocate like this:
arr = malloc(size * sizeof(int*));
for (int i = 0; i <size; i++)
arr[i] = malloc(size * sizeof(int));
And do not forget to free the memeory using free.
Side Note: Do not cast the return value of malloc.
One idea that would work and would also get you rid of the memory fragmentation induced by this double pointers level allocation is make your matrix linear:
arr = (int*) malloc (size*size*sizeof(int));
And then simply access your elements with arr[i*size + j] instead of arr[i][j]:
use it like this : a perfect example of dynamic memory Allocation
void mxmult()
{
int n,m,a,b,c,d, sum=0;
int x,y,z;
printf("Enter first order [n*n]\n");
scanf("%d", &n);
printf("Enter second order [m*m]\n");
scanf("%d", &m);
if (n!=m)
{
printf("Invalid orders");
}
else
{
//mem allocate for matrix 1
int **mat1 = (int**)malloc(n*sizeof(int));
for(x=0;x<n;x++)
{
mat1[x]=(int*)malloc(n*sizeof(int));
}
// input matrix 1
printf("Enter the first matrix entries\n");
for (a = 0; a <n; a++)
{
for (b = 0; b < n; b++)
{
scanf("%d", &mat1[a][b]);
}
}
// memory allocate matrix 2
int **mat2 = (int**)malloc(m*sizeof(int));
for(y=0;y<n;y++)
{
mat2[y]=(int*)malloc(m*sizeof(int));
}
//inpur matrix 2
printf("Enter the second matrix entries\n");
for (c = 0; c <n; c++)
{
for (d= 0; d < n; d++)
{
scanf("%d", &mat2[c][d]);
}
}
//Memory allocate matrix Mult
int **mult=(int**)malloc(m*sizeof(int));
for(z=0;z<m;z++)
mult[z]=(int*)malloc(m*sizeof(int));
for (a = 0; a < n; a++)
{
for (d = 0; d < m; d++)
{
for (c = 0; c < n; c++)
{
sum=sum + (mat1[a][c] *mat2[c][d]);
}
mult[a][d] = sum;
sum= 0;
}
}
printf("Product\n");
for ( a = 0 ; a < n ; a++ )
{
for ( d = 0 ; d < m ; d++)
printf("%d\t", mult[a][d]);
printf("\n");
}
}
}
Related
thanks for taking the time in reading this.
In my question a "vector" is defined as a 1D dimensional array of integers.
Therefore an array of vectors would be a 2D dimensional array in which every vector can be of a different length.
I'm asked to use:
int** vectors- the 2D array
int size -an integer that represents how many vectors exist inside **vectors
int* sizes-a 1D array of integers that represents the length of the vectors
for example,for:
vectors = {{4,3,4,3},{11,22,33,44,55,66},NULL,{5},{3,33,333,33,3}}.
size is 5 (there are 5 vectors inside vectors).
sizes is {4,6,0,1,5} (4 is the length of the first vector and so on).
size is inputted by the user at the beginning of main() and **vectors&*sizes are dynimacilly allocated with size's value.
I'm asked to write the function:
int init(int ***vectors, int **sizes, int size) which initializes **vectors to be an array of NULLs and *sizes to be an array of zeros.
I came up with this code:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
int init(int*** vectors, int** sizes, int size)
{
int i, k,j;
printf("check\n");
*vectors = (int**)malloc(size * sizeof(int*));
if (*vectors == NULL)
return 0;
for (i = 0; i < size; i++)
{
*(vectors + i) = NULL;
}
printf("check 2\n");
for (k = 0; k<size; k++)
{
if (*(vectors+k) != NULL)
printf("didn't work\n");
else
printf("current is null\n");
}
*sizes= (int*)malloc(size * sizeof(int));
if (*sizes == NULL)
return 0;
for (j= 0; j < size; j++)
{
*(sizes + j) = 0;
printf("%d ", *(sizes + j));
}
printf("\n");
return 1;
}
int main()
{
int size, i;
int** vectors = NULL;
int* sizes = NULL;
printf("\nPlease enter an amount of vectors:\n");
scanf("%d", &size);
printf("%d\n", init(&vectors, &sizes, size));
printf("size is %d now\n", size);
// for (i = 0; i < size; i++)
// printf("%d ", *(sizes+i));
printf("check 3\n");
free(sizes);
free(vectors);
printf("check 4\n");
printf("check 5\n");
return 0;
}
forgot to mention that init returns 0 if it fails to allocate memory and 1 otherwise.
printing the "checks" was so I could see where the program fails.
the problem is that no matter what,after printing the last check (check 5)
the program fails.(Run-Time Check Failure #2)
if anyone could help me understand what I'm doing wrong I would HIGHLY appreciate it.
thanks alot for reading and have an amazing day.
edit:
i also printed the array sizes/vectors inside init just to see if it prints zeros/nulls,i don't actually need to do it.
One problem of OP's code is in the pointer arithmetic. Given:
int ***vectors;
*vectors = malloc(size * sizeof(int*));
This loop:
for (i = 0; i < size; i++)
{
*(vectors + i) = NULL;
}
Would iterate over the next unallocated pointer to pointer to pointer to int, while what the OP needs is
for (i = 0; i < size; i++)
{
*(*vectors + i) = NULL; // or (*vectors)[i] = NULL;
}
The same holds in the following loops, where *(sizes + j) is used instead of *(*sizes + j) (or (*sizes)[j]).
This question already has answers here:
2D array dynamic memory allocation crashes [duplicate]
(2 answers)
Closed 6 years ago.
I'm a newbie trying to learn how to make dynamics arrays in C. The code doesn't give me any errors when I build it using code:blocks, but when I run it crashes. I think the crash has to do with the way I'm freeing my memory, because the code is giving me the desired output before crashing.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int i, j;
int *p = (int *)malloc(sizeof(*p));
printf("Hello World! I have created a dynamic array of 20x30 integers! \n");
for (i = 0; i <= 19; i++)
{
p[i] = (int )malloc(sizeof(int*));
printf(" %2d ", i);
for (j = i + 1; j <= 29 + i; j++)
{
p[i] = 0;
printf("%2d", j);
}
printf("\n");
}
for (i = 0; i <= 19; i++);
{
free(p[i]);
}
free(p);
return 0;
}
Here's the problem.
First, your first malloc call allocates space for a 1-element array.
You'll want to change it from
int *p = (int *)malloc(sizeof(*p));
to
int *p = (int *)malloc(sizeof(int*) * 20);
And then your second malloc call is slightly incorrect as well.
p[i] = (int )malloc(sizeof(int*));
should be changed to
p[i] = (int *)malloc(sizeof(int));
You just put the asterisk in the wrong place.
Finally, you really only create a 20-element array. All you do in the inner for loop is assign each cell in the array the value 0 times. If you want to make a 20x30 array, you can always take the easy route and create a 1D array and use some math (which is ultimately what the compiler does with non-dynamic 2D arrays anyway):
int main()
{
int *p = (int *)malloc(sizeof(int) * 600);
...
for (i = 0; i <= 19; i++)
{
printf(" %2d ", i);
for (j = 0; j <= 29; j++)
{
p[i * 30 + j] = 0; // It's i * 30, not i * 20 because you have to skip the space that the 'j' dimension takes up.
printf("%2d", j);
}
printf("\n");
}
free((void*)p); //I found the program crashes without the void* cast
}
I've tested this code and it runs.
Hope this helps.
In the following homework assignment:
Create an array of 100 random numbers in the range of 1…999, write a function for each of the following processes. In building the array, if 3 or 7 evenly divide the random number, store it as a negative number.
a. Print the array ten values to a line. Make sure that the values are aligned in rows.
b. Return a count of the number of even values
c. Return the sum of all values in the array
Create a two dimensional array (size 10 X 10). Fill this two dimensional array with the values from the above single dimensional array. Determine the maximum value in each row. Display the two-dimensional array and the maximum of each row.
3. Repeat number 2 above but this time instead of 10 X 10 array, prompt the user for the size of the row and column, allow user to fill in the values and display the array.(Hint: Use pointers and dynamic memory allocation )
I'm stuck on number 3. I'm not sure how to correctly use the dynamic memory allocation and pointers to make room for the number of rows and columns the user inputs.
int main(void)
{
int hundred[100];
cien(hundred);
even(hundred);
total(hundred);
two_dim(hundred, table);
hi_row(table);
cust_arr(hundred,table);
system("pause");
return 0;
}
void cien(int hundred[])
{
int i = 0;
int range = (999 - 1) + 1;
for (i = 0; i < 100; i++)
{
hundred[i] = rand() % range + 1;
if (hundred[i] % 3 == 0 || hundred[i] % 7 == 0)
{
hundred[i] = hundred[i] * -1;
printf("%d\t", hundred[i]);
}
else
{
printf("%d\t", hundred[i]);
}
}
return;
}
int two_dim(int hundred[], int arr[][10])
{
int x;
int y;
int i = 0;
int table[10][10];
while (i != 100)
{
for (x = 0; x <10; x++)
{
for (y = 0; y < 10; y++)
{
arr[x][y] = hundred[i];
printf("%d\t", arr[x][y]);
i++;
}
}
}
return **table;
}
void** cust_arr(int hundred[], int table[][10])
{
int x, y, i, j, k=0;
int **arr;
printf("input the number of rows.\n" );
scanf_s("%d", &x);
i = (int*)calloc(x, sizeof(int*));
printf("input the number of columns.\n");
scanf_s("%d", &y);
j = (int*)calloc(y, sizeof(int*));
while (k != 100)
{
for (i = 0; i <= x; i++)
{
for (j = 0; j <= y; j++)
{
hundred[k] = table[10][10];
table[10][10] = **arr[i][j];
}
}
printf("%d\n", **arr[i][j]);
k++;
}
}
Since the prompt says to repeat number 2, I have tried to make similar loops in my cust_arr() function
malloc will return a pointer the the memory region allocated. You can use brackets on pointers to specify an index just like static arrays. Since you need a 2d array, you need a pointer pointing to an array of pointers i.e. the columns point to the rows, the rows point to the values.
int ** dynamicPointer = malloc(sizeof(int*)*columns);
for(int i = 0; i < columns; i++)
dynamicPointer[i] = malloc(sizeof(int)*rows);
//address of final column and row
dynamicPointer[columns- 1][rows - 1] = 3;
print("%d\n", dynamicPointer[columns- 1][rows - 1]);
For 10x10 array I would suggest using variable length arrays. If you want to use dynamic allocation then use malloc function.
int x, y;
int **table;
scanf("%d %d", &x, &y);
table = malloc(x*sizeof(int *));
for(int i = 0; i < x; i++)
table[i] = malloc(y*sizeof(int));
Beside this, the code shown has many flaws and need to be fixed. Better to put all the function declaration and definition outside the function with specifying their return type and parameters.
I followed few examples on this forum, but it seems like my program still keeps crashing at some point.
All i want to do is just use a void function for memory allocation.
void alloc(int ***matrix, int n)
{
int i = 0;
for( ; i < n; i++)
{
(*matrix)[i] = (int*)malloc(n * sizeof(int));
}
i = 0;
for( ; i < n; i++)
{
int j = 0;
for( ; j < n; j++)
{
(*matrix)[i][j] = i * j;
}
}
}
//-------------------------------------------------------------------
int main()
{
int n;
int **matrix_pp;
printf("Enter n: ");
scanf("%d", &n);
alloc(&matrix_pp, n);
free(matrix_pp);
return 0;
}
You try to use (*matrix)[i] before it's been allocated. Add:
(*matrix) = malloc(n * sizeof(**matrix));
before your for loop.
Note two things here:
1) Don't cast the result of malloc,
2) use sizeof(*pointer) instead of explicitly writing out the type; this way, if you decide to change the type later, it will still work.
Further, you will need to free all of the allocations you have in a loop as a loop as well; otherwise, you have a memory leak.
I have to implement code to find the Binomial Coefficient using dynamic programming. But I don't know how to set the array B. Here the code I have:
#include <stdio.h>
int minimum(int a, int b) { return (a < b) ? a : b; }
main() {
int n = 50, k;
printf("Enter value for k:");
scanf("%d", &k);
printf("Value of coefficient %d, %d is: %d\n", n, k, bin2(n, k));
return 0;
}
// code to be implemented
int bin2(int n, int k) {
int i, j;
// array to initialize. Help
int B[0..n][0..k];
for (i = 0; i <= n; i++)
for (j = 0; j <= minimum(i, k); j++)
if (j == 0 || j == i)
B[i][j] = 1;
else
B[i][j] = B[i - 1][j - 1] + B[i - 1][j];
return B[n][k];
}
You can use the malloc() and calloc() functions from <stdlib.h> to allocate memory on the fly. Since you want to be able to store indices from 0 to n and 0 to k, you have to create a (n+1) × (k+1) array. This is done by allocating an array of n+1 int* pointers, then assigning an array of k+1 int values to each pointer:
/* Initialize array */
B = malloc((n+1) * sizeof(int*));
for (i=0; i<=n; i++) B[i] = calloc((k+1), sizeof(int));
When your function exits, this memory will still be allocated, but you will no longer be able to access it because the value of B is local to the bin2() function and will be lost forever. (This is called a memory leak.)
So you need to free up this memory before returning:
int result = B[n][k];
/* Dispose of array */
for (i=0; i<=n; i++) free(B[i]);
free(B);
return result;
}
(By the way, this isn't dynamic programming you're asking about, it's dynamic memory allocation. And there are better ways of calculating binomial coefficients.)