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;
}
Related
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);
}
// .....
So i have this example:
3 4 6 11 4 6 38 7 6 9
I need to get from user several numbers and create multi dimension array.
The first number N (3 in my example) mean that my array (or matrix) will contain N² value and insert all this numbers (the next 9 values) into my array.
So first i need to define the array according my first value (3 in my example) and create my array:
int a[3][3];
The catch here is that i need to get all my input in a single line so i cannot use this:
int marks[3];
int i;
for(i=0;i<3;i++)
{
printf("Enter a no\n");
scanf("%d",(marks+i));
}
scanf reads data from stdin and stores them according to the parameter format into the locations pointed by the additional arguments.
scanf will store whole the input from stdin, so it really does not matter if it is in single line or not. The way for your code is just, simply ask user for dimensions and create the variable of the given dimension and fill each value with a scanf.
There are 3 ways to do it :
If your compiler supports variable length array:
int size,i,j;
scanf("%d",&size);
int matrix[size][size];
for(i=0;i<size;i++)
{
for(j=0;j<size;j++)
{
scanf("%d",&matrix[i][j]);
}
}
Does not support variable length array: (using array of pointers)
int size,i,j;
scanf("%d",&size);
int **matrix;
matrix = (int **)malloc(sizeof(int *) * size);
for(i=0;i<size;i++)
{
matrix[i] = (int *)malloc(sizeof(int) * size);
}
for(i=0;i<size;i++)
{
for(j=0;j<size;j++)
{
scanf("%d",&matrix[i][j]);
}
}
This looks easy but the way is very poor as it is not actually an 2D array but an array of pointers. hence, I suggest to use the 3rd way if your compiler does not support variable length array.
Using malloc: (with pointer)
Create Array of integers like:
int size;
scanf("%d",&size);
int *matrix;
matrix = (int *) malloc( sizeof(int) * size * size );
Now, to fill or get the values of the Array you need to traverse to the particular value.
to fill:
for(i=0;i<size;i++)
{
for(j=0;j<size;j++)
{
scanf("%d", (matrix + i*(size) + j));
}
}
to iterate: (print in this case)
for(i=0;i<size;i++)
{
for(j=0;j<size;j++)
{
printf("%d " ,*(matrix+ i*size + j) );
}
printf("\n");
}
Note: It is very important to constrain the input and check whether it lies in some fixed range or not. for ex: ( 0 < size < 100). It is very simple and you can do it yourself. I have answered the important parts only :)
To begin with, you can't store 10 numbers in a 3x3 matrix. Always make sure your specification makes sense before you start programming.
Taking the input is trivial, just use a nested loop to control where the read input ends up in your matrix. Example with a fixed array size:
#include <stdio.h>
#include <stdlib.h>
#define x 3
#define y 3
int main (void)
{
int arr[x][y];
printf("Enter %d numbers: ", x*y);
for(size_t i=0; i<x; i++)
{
for(size_t j=0; j<y; j++)
{
scanf(" %d", &arr[i][j]);
}
}
for(size_t i=0; i<x; i++)
{
for(size_t j=0; j<y; j++)
{
printf("%d ", arr[i][j]);
}
printf("\n");
}
return 0;
}
(Note that this leaves a whole lot of junk like line feed characters behind in stdin. There's also no buffer overflow protection. See How to read / parse input in C? The FAQ for examples of how to read input properly.)
If you need a variable size matrix, you can use variable length arrays (VLA):
size_t x = 3; // some run-time value
size_t y = 3; // some run-time value
int arr[x][y];
... // then same code as above
Alternatively, you can use a dynamically allocated 2D array:
#include <stdio.h>
#include <stdlib.h>
int main (void)
{
size_t x = 3;
size_t y = 3;
int (*arr)[y] = malloc( sizeof(int[x][y]) );
printf("Enter %zu numbers: ", x*y);
for(size_t i=0; i<x; i++)
{
for(size_t j=0; j<y; j++)
{
scanf(" %d", &arr[i][j]);
}
}
for(size_t i=0; i<x; i++)
{
for(size_t j=0; j<y; j++)
{
printf("%d ", arr[i][j]);
}
printf("\n");
}
free(arr);
return 0;
}
Alternatively, if your compiler is from the Jurassic period, you can use old style "mangled" 2D arrays:
#include <stdio.h>
#include <stdlib.h>
int main (void)
{
size_t x = 3;
size_t y = 3;
int* mangled = malloc(x * y * sizeof *mangled);
printf("Enter %zu numbers: ", x*y);
for(size_t i=0; i<x; i++)
{
for(size_t j=0; j<y; j++)
{
scanf(" %d", &mangled[i*x + j]);
}
}
for(size_t i=0; i<x; i++)
{
for(size_t j=0; j<y; j++)
{
printf("%d ", mangled[i*x + j]);
}
printf("\n");
}
free(mangled);
return 0;
}
The above 4 alternatives are the only alternatives. You should not use "pointer-to-pointer look-up tables", there is absolutely no need for them here. Unfortunately, lots of bad books and bad teachers spread that technique. See Correctly allocating multi-dimensional arrays.
Try this:
int** InitMatrix()
{
int** matrix = NULL;
int n;
if (scanf("%d", &n) > 0 && n > 0)
{
matrix = malloc(n * sizeof(int*));
for (int i = 0; i < n; i++)
{
matrix[i] = malloc(n * sizeof(int));
for (int j = 0; j < n; j++)
{
if (scanf("%d", &matrix[i][j]) == 0)
{
// user input error; decide what to do here
}
}
}
}
else
{
// user input error; decide what to do here
}
return matrix;
}
I have assignment to write program that sort an array and search for a specific number, that part I've already done, My problem is how to Initialize the array in the size that the user sets with random values smaller than 500? I know how to do that with known size but not with unknown size?
example for input/output:
"Please enter the size of the array:
5"
This will help you.
int main(void)
{
int n,i;
n=rand()%500; // Get random value
int arr[n]; // Initialize the dynamic array
for(i=0;i<n;i++)
scanf("%d",&arr[i]);
// Do your stuff
}
You can do something like this:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void printArray(int* p, int size)
{
for (int j = 0; j < size; ++ j) printf("%d ", p[j]);
printf("\n");
}
int main(void) {
srand(time(NULL)); // Start with a random seed based on time
int n = 0;
printf("Which array size do you need?\n");
if (scanf("%d", &n) != 1 || n < 1)
{
printf("Wrong input\n");
exit(0);
};
printf("Creating random array of size %d\n", n);
int* p = malloc(n * sizeof(*p)); // Reserve memory
for (int j = 0; j < n; ++j) p[j] = rand() % 500; // Generate random numbers
printArray(p, n); // Print the result
free(p); // free the allocated memory
return 0;
}
So I have a problem:
My program has to find the most common element in an array. We have to make this array with calloc. My code is working but I am asked to move part of my code to a function in which I have to create an array and enter numbers.
int main() {
int n, i, dazn;
int *A;
dazn = 0;
printf("Iveskite naturalu skaiciu: \n");// enter how many elements in an array we will have
scanf("%d", &n);
A = (int*)calloc(n, sizeof(int)); // Starting from here...
for (i = 0; i < n; i++) {
printf("Iveskite skaiciu \n");
scanf("%d", &A[i]); //
}
... // and ending here have to be in a function
... // sorting and finding the most common element
As instructed, move the code to a separate function:
#include <stdio.h>
#include <stdlib.h>
int *allocate_and_read_array(int size) {
int *A = (int*)calloc(size, sizeof(int));
if (A != NULL) {
for (int i = 0; i < size; i++) {
printf("Iveskite skaiciu \n");
if (scanf("%d", &A[i]) != 1) {
printf("Missing values\n");
break;
}
}
}
return A;
}
int main(void) {
int n, i, dazn;
int *A;
dazn = 0;
printf("Iveskite naturalu skaiciu: \n");// enter how many elements in an array we will have
scanf("%d", &n);
A = allocate_and_read_array(n);
... // sort the array
... // find the most common element
free(A);
return 0;
}
Here is my try. I am not totally sure about my manipulations with the pointer. Maybe this is why I am wrong, maybe there is some other case. I want to take the dimensions from the user and create a square matrix, make some manipulations with its elements, and display the original and results to the user. Last time I accomplished this by creating a 100x100 array, and specifying the end of each line, and end of lines by constants. Then I would print all the elements up to this constant. But it does not seem to be right to create a 100x100 array for 4x4 matrices. I could create a smaller array, but this does not seem to be the right solution to the problem. Is there a way in C to create a 2d array exactly the size specified by the users (it will be a square array). Thanks
#include <stdio.h>
#include <stdlib.h>
double * createMatrix(int dimentions);
void drawMatrix(double * matrix);
int main(void)
{
int n, i, j;
system("cls");
system("color 70");
system("pause");
puts("Enter the matrix's dimension");
scanf("%i", &n);
double * pmatrix = createMatrix(n);
for (i = 0; i < n; ++j)
for (j = 0; j < n; ++j)
{
printf("A%i%i: ", i + 1, j + 1);
scanf("%lf", pmatrix[i][j]);
getchar();
}
for (i = 0; i < n; ++i)
{
putchar('\n');
for (j = 0; j < n; ++j)
printf(" %lf ", &pmatrix[i][j]);
}
system("color 08");
return 0;
}
double * createMatrix(int n)
{
const int N = n;
const int N1 = N;
double matrix[N][N];
double * pmatrix = matrix;
return pmatrix;
}
You can create a matrix directly; you don't need a function for that. Replace the code
double * pmatrix = createMatrix(n);
by the regular way of declaring a 2-D array:
double matrix[n][n];
One more way of doing it using pointers.
#include <stdio.h>
#include <stdlib.h>
int main (int argc, char *argv[])
{
double **pmatrix;
int rowsize, colsize, i, j;
printf("Enter the number of rows: ");
scanf("%d",&rowsize);
printf("Enter the number of columns: ");
scanf("%d",&colsize);
//Allocate memory for 2D array
pmatrix = malloc(rowsize*sizeof(double*));
for(i=0;i<rowsize;i++)
{
pmatrix[i] = malloc(colsize*sizeof(int));
}
//Accepting the values
for(i=0;i<rowsize;i++)
{
for(j=0;j<colsize;j++)
{
printf("A %i %i: ", i + 1, j + 1);
scanf("%lf",&pmatrix[i][j]);
}
}
//Printing the values
for(i=0;i<rowsize;i++)
{
for(j=0;j<colsize;j++)
{
printf("%lf\t",pmatrix[i][j]);
}
printf("\n");
}
//Free the memory
for(i=0;i<rowsize;i++)
free(pmatrix[i]);
free(pmatrix);
return 0;
}