I am trying to swap two structs in C. The issue is I have to use malloc() in order to allocate memory for n number of structs during run-time. The structs have to accessed using the base pointer of the memory allocated by malloc(). I also tried typecasting (triangle*)malloc() But that didn't work either. Can anyone tell me how to do this?
My Code:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
struct triangle
{
int a;
int b;
int c;
};
typedef struct triangle triangle;
void swapStructs(triangle *a, triangle *b)
{
triangle temp = *a;
*a = *b;
*b = temp;
}
void print_structs(triangle *tr, int n)
{
printf("VALUES BEFORE SWAPPING...\n");
for(int i=0; i<n; i++)
{
printf("A[%d]: %d\n", i ,tr->a);
printf("B[%d]: %d\n", i ,tr->b);
printf("C[%d]: %d\n", i ,tr->c);
tr++;
}
swapStructs(&tr[0], &tr[1]);
printf("VALUES AFTER SWAPPING...\n");
for(int i=0; i<n; i++)
{
printf("A[%d]: %d\n", i ,tr->a);
printf("B[%d]: %d\n", i ,tr->b);
printf("C[%d]: %d\n", i ,tr->c);
tr++;
}
}
int main()
{
int n;
scanf("%d", &n);
triangle *tr = malloc(n * sizeof(triangle));
for (int i = 0; i < n; i++)
{
scanf("%d %d %d", &tr[i].a, &tr[i].b, &tr[i].c);
}
swapStructs(&tr[0], &tr[1]);
print_structs(tr, n);
return 0;
}
Rather than printing the correct output, it printed garbage values.
Just remove the tr++; instructions.
Also the print_structs should be fixed as follow:
void print_structs(triangle *tr, int n)
{
printf("VALUES BEFORE SWAPPING...\n");
for(int i=0; i<n; i++)
{
printf("A[%d]: %d\n", i ,tr[i].a);
printf("B[%d]: %d\n", i ,tr[i].b);
printf("C[%d]: %d\n", i ,tr[i].c);
}
swapStructs(&tr[0], &tr[1]);
printf("VALUES AFTER SWAPPING...\n");
for(int i=0; i<n; i++)
{
printf("A[%d]: %d\n", i ,tr[i].a);
printf("B[%d]: %d\n", i ,tr[i].b);
printf("C[%d]: %d\n", i ,tr[i].c);
}
}
Related
Link
here is link to question. In this question we have to sort the triangles based on their areas and then print out the dimensions of triangle in sorted format.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
struct triangle
{
int a;
int b;
int c;
};
typedef struct triangle triangle;
void sort_by_area(triangle* tr, int n) {
/**
* Sort an array a of the length n
*/
double arr[n+1];
triangle temp;
for(int i=0;i<n;i++)
{
double area_2,p;
p=((tr[i].a+tr[i].b+tr[i].c)/2.0);
area_2=(p*(p-tr[i].a)*(p-tr[i].b)*(p-tr[i].c));
arr[i]=area_2;
}
for(int i=0;i<n-1;i++)
{
for(int j=i+1;j<n;j++)
{
if(arr[i]>arr[j])
{
temp=tr[i];
tr[i]=tr[j];
tr[j]=temp;
}
}
}
}
int main()
{
int n;
scanf("%d", &n);
triangle *tr = malloc(n * sizeof(triangle));
for (int i = 0; i < n; i++) {
scanf("%d%d%d", &tr[i].a, &tr[i].b, &tr[i].c);
}
sort_by_area(tr, n);
for (int i = 0; i < n; i++) {
printf("%d %d %d\n", tr[i].a, tr[i].b, tr[i].c);
}
return 0;
}
This is my code. Only sample testcase is getting passed with this code and all else testcases are wrong. can someone pls help me with this?
Thanks a lot guys for your help. finally with lots of debugging, i understood the error in my code. while swapping the structure array i was forgetting to swap the area array as well.Here is the code for this:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
struct triangle
{
int a;
int b;
int c;
};
typedef struct triangle triangle;
#define longlong int;
void swap(double *array,int i,int j)
{
int temp=array[i];
array[i]=array[j];
array[j]=temp;
}
void sort_by_area(triangle* tr, int n) {
double arr[n];
triangle temp;
for(int i=0;i<n;i++)
{
double area_2,p;
p=((tr[i].a+tr[i].b+tr[i].c)/2.0);
area_2=(p*(p-tr[i].a)*(p-tr[i].b)*(p-tr[i].c));
arr[i]=area_2;
/*storing square of area in a different array of different types of triangle*/
}
for(int i=0;i<n;i++)
{
for(int j=i+1;j<n;j++)
{
if(arr[i]>arr[j])
/*using bubble sort comparing the area of subsequent triangles and if area of subsequent triangles are found to be greater than the previous one then swapping the areas as well as the structure array*/
{ swap(arr,i,j);
temp=tr[i];
tr[i]=tr[j];
tr[j]=temp;
}
}
}
}
int main()
{
int n;
scanf("%d", &n);
triangle *tr = malloc(n * sizeof(triangle));
for (int i = 0; i < n; i++) {
scanf("%d%d%d", &tr[i].a, &tr[i].b, &tr[i].c);
}
sort_by_area(tr, n);
for (int i = 0; i < n; i++) {
printf("%d %d %d\n", tr[i].a, tr[i].b, tr[i].c);
}
return 0;
}
I feel like I've attempted every combination I know of to get this to work and can't figure it out. How can I scanf() into an int** passed as a pointer to a function? I tried searching but couldn't find this, if it's a duplicate please let me know and I'll delete. It begins to run and after entering a few values it segfaults.
Here's my code, I think it's messing up on the scanf() line of the setMatrix() function:
#include <stdio.h>
#include <stdlib.h>
// create zero initialized matrix
int** callocMatrix(int rmax, int colmax) {
int **mat = calloc(rmax, sizeof(int*));
for(int i = 0; i < rmax; i++) mat[i] = calloc(colmax, sizeof(int));
return mat;
}
// fill matrix
void setMatrix(int ***mat, int r, int c){
printf("Insert the elements of your matrix:\n");
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) {
printf("Insert element [%d][%d]: ", i, j);
scanf("%d", mat[i][j]); // problem here??
printf("matrix[%d][%d]: %d\n", i, j, (*mat)[i][j]);
}
}
return;
}
// print matrix
void printMatrix(int ***mat, int r, int c){
for (int i=0; i<r;i++){
for (int j=0; j<c;j++) {
printf("%d ", (*mat)[i][j]);
}
printf("\n");
}
}
int main(int argc, char *argv[]) {
int r = 3, c = 3;
int **mat = callocMatrix(r, c);
setMatrix(&mat, r, c);
printMatrix(&mat, r, c);
}
There is no need to use triple pointer ***. Passing two-dimensional array will work as is. Here is the code:
#include <stdio.h>
#include <stdlib.h>
// create zero initialized matrix
int** callocMatrix(int rmax, int colmax) {
int **mat = calloc(rmax, sizeof(int*));
for(int i = 0; i < rmax; i++) mat[i] = calloc(colmax, sizeof(int));
return mat;
}
// fill matrix
void setMatrix(int **mat, int r, int c){
printf("Insert the elements of your matrix:\n");
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) {
printf("Insert element [%d][%d]: ", i, j);
scanf("%d", &mat[i][j]); // no problem here
printf("matrix[%d][%d]: %d\n", i, j, mat[i][j]);
}
}
}
// print matrix
void printMatrix(int **mat, int r, int c){
for (int i=0; i<r;i++){
for (int j=0; j<c;j++) {
printf("%d ", mat[i][j]);
}
printf("\n");
}
}
int main(int argc, char *argv[]) {
int r = 3, c = 3;
int **mat = callocMatrix(r, c);
setMatrix(mat, r, c);
printMatrix(mat, r, c);
}
Should be:
scanf("%d", &(*mat)[i][j]);
You're passing a pointer to you matrix object, so you need to dereference it (with *) just as you do with printf. scanf then needs the address of the element to write into, so you need the &
I have two 2d arrays "a", "b" (empty array) with the same size, I have to change "a" due to a certain function that save it's new values in "b", then I have to change the new values according to the same function, so the program will save b's new values in a and then back to a.
When the arrays are printed only the first two ones are printed!!
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MSIZE 10
void new_gen(char * a[MSIZE],int s,char** b); /*the function we talked about*/
void print_m(char** b,int s); /*prints matrix*/
void cpy_m(char** b, char** a, int s);
int main()
{
int Size, gen, i, j;
printf("Enter number of generations\t");
scanf("%d", &gen);
printf("\nEnter size of the matrix (max size is %d and min is 2)\t", MSIZE);
scanf("%d", &Size);
char **m = (char**) malloc(Size*sizeof(char*));
for (i=0; i<Size; i++)
{
m[i] = (char*) malloc(Size*sizeof(char));
}
printf("Enter matrix of first generation\n");
for (i=0; i<Size; i++) {
for (j=0; j<Size; j++) {
scanf(" %c", &m[i][j]);
}
}
print_m(m, Size);
for (i=1; i<gen; i++)
{
char **n = (char**) malloc(Size*sizeof(char*));
for (i=0; i<Size; i++)
{
n[i] = (char*) malloc(Size*sizeof(char));
}
new_gen(m, Size, n);
print_m(n, Size);
cpy_m(n, m, Size);
}
return 0; }
void print_m(char** b, int s)
{
int i, j;
putchar('\n');
for (i=0; i<s; i++)
{
for (j=0; j<s; j++) {
printf("%c", *(*(b+i)+j));
}
putchar('\n');
}
return;
}
void cpy_m(char* b[MSIZE],char** a, int s)
{
int i, j;
for (i=0; i<s; i++) {
for (j=0; j<s; j++) {
*(*(a+i)+j) = b[i][j];
}
return;
}}
Consider this pair of nested loops
for (i=1; i<gen; i++)
{
char **n = (char**) malloc(Size*sizeof(char*));
for (i=0; i<Size; i++)
{
n[i] = (char*) malloc(Size*sizeof(char));
}
new_gen(m, Size, n);
print_m(n, Size);
cpy_m(n, m, Size);
}
First point, both the loops use i as the control variable, but they are nested.
Second point, you overwrite the pointers from malloc in each iteration (there is no free).
Given m points in the plane. Number of xy coordinates must be
entered via the keyboard. How to find this coordinates from xy? With two-dimensional dynamic array.
Now I have this but it's not working:
int **enterPoints (int m) {
int i, **points;
scanf("%d",&m);
points = (int **)malloc(m*sizeof(int *));
if (points != NULL) {
for (i=0; i<m; i++) {
*(points+i) = (int *)malloc(m*sizeof(int));
if (*(points+i)==NULL)
break;
}
{
printf("enter %d points coord X and Y:", i+1);
scanf("%d %d", &*(*(points+i)+0), &*(*(points+i)+1));
*(*(points+i)+2)=0;
}
}
free(points);
return points;
}
try this
#include <stdio.h>
#include <stdlib.h>
int **enterPoints (int m){
int i, **points;
//scanf("%d",&m);//already get as argument
if(m<=0)
return NULL;
points = (int**)malloc(m*sizeof(int*));
if (points != NULL){
for (i=0; i<m; i++){
points[i] = (int*)malloc(2*sizeof(int));
if(points[i]!=NULL){
printf("enter %d points coord X and Y:", i+1);fflush(stdout);
scanf("%d %d", &points[i][0],&points[i][1]);
}
}
}
//free(points);//free'd regions is unusable
return points;
}
int main(void){
//test code
int i, m, **points;
//scanf("%d", &m);
m = 3;
points = enterPoints(m);
for(i = 0; i < m; ++i){
printf("(%d, %d)\n", points[i][0], points[i][1]);
free(points[i]);
}
free(points);
return 0;
}
I don't have a lot of experience with pointers, but I want to try to make an array of pointers, each pointer pointing to a scanned string.
For example, you first input how many strings you want to scan (for example 5), and then I want to scan those strings and make an array of 5 pointers that point to those strings.
Because I didn't have a lot experience with something like this, I first tried it with normal arrays instead of strings, what I got is this:
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<assert.h>
int **array(int m, int n) {
int i, j;
int **array = malloc(n*sizeof(int*));
for (j=0; j<m; j++) {
for (i=0; i<n; i++) {
array[i]=malloc(m * sizeof(int));
scanf("%d", &array[j][i]);
printf("array[%d][%d] is scanned and has value %d\n", j, i, array[j][i]);
}
}
return array;
}
int main(int argc, char*argv[]){
int m, n, *p, k;
scanf("%d %d", &m, &n);
printf("m is %d and n is %d\n", m, n);
p=*array(m, n);
printf("the numbers are:\n");
for (k=0; k<m*n; k++) {
printf("%d\n", p[k]);
}
return 0;
}
But here it's already going wrong, and I don't know why...
At the last printf, I always get wrong numbers, 0's and 17's...
Can someone explain me why this is and what I'm doing wrong? I think it's something with the returning of the array but I'm not sure..
If someone could explain this to me it would be great.
The problem with your code is the following:
// m = 3, n = 5
// array = ptr1, ptr2, ptr3, ptr4, ptr5
// | |
// 3 ints |
// 3 ints ..
int **array(int m, int n) {
int i, j;
int **array = (int**)malloc(n*sizeof(int*));
for (j=0; j<m; j++) {
for (i=0; i<n; i++) {
array[i]=(int*)malloc(m * sizeof(int));
scanf("%d", &array[j][i]);
printf("array[%d][%d] is scanned and has value %d\n", j, i, array[j][i]);
}
}
return array;
}
In the above example (m=3, n=5) you allocated 5 pointers to integers and then tried to populate them by allocating memory at each iteration in the inner-loop (WRONG). If you allocate new memory at each iteration, you're gonna lose the pointer to the previously allocated memory and the data you stored!
Plus the indices seem to be wrong for the inner and outer loop, a correct version of your code is:
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<assert.h>
// 3, 5
// array = ptr1, ptr2, ptr3, ptr4, ptr5
// | |
// 3 ints |
// 3 ints ..
int **array(int m, int n) {
int i, j, index;
int **array = (int**)malloc(n*sizeof(int*));
index = 0;
for (j=0; j<n; j++) {
array[j]=(int*)malloc(m * sizeof(int)); // Allocate once per each j
for (i=0; i<m; i++) {
array[j][i] = index++;
printf("array[%d][%d] is scanned and has value %d\n", j, i, array[j][i]);
}
}
return array;
}
int main(int argc, char*argv[]){
int m, n, **p, k, i, j;
m = 3;
n = 5;
printf("m is %d and n is %d\n", m, n);
p=array(m, n);
printf("the numbers are:\n");
for (j=0; j<n; j++)
for(i=0; i<m; i++)
printf("%d\n", p[j][i]);
return 0;
}
And the above version is STILL NOT CORRECT : You need to free the allocated memory!
I'll leave that as an exercise.. hint: you CAN'T simply do "free(p);" :]
Are you sure about this for loop? If you've the malloc inside the inner loop you're not creating a matrix because every time you override the same cells...
int i, j;
int **array = malloc(n*sizeof(int*));
for (j=0; j<m; j++) {
for (i=0; i<n; i++) {
array[i]=malloc(m * sizeof(int));
scanf("%d", &array[j][i]);
printf("array[%d][%d] is scanned and has value %d\n", j, i, array[j][i]);
}
}
It should be something like:
int i, j;
int **array = malloc(n*sizeof(int*));
for (i=0; i<n; i++) {
array[i]=malloc(m * sizeof(int));
for (j=0; j<m; j++) {
scanf("%d", &array[i][j]);
printf("array[%d][%d] is scanned and has value %d\n", i, j, array[i][j]);
}
}
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<assert.h>
void *array(int m, int n) {
int i, j;
int (*array)[n] = malloc(sizeof(int [m][n]));//m*n*sizeof(int)
for (j=0; j<m; j++) {
for (i=0; i<n; i++) {
scanf("%d", &array[j][i]);
printf("array[%d][%d] is scanned and has value %d\n", j, i, array[j][i]);
}
}
return array;
}
int main(int argc, char*argv[]){
int m, n, *p, k;
scanf("%d %d", &m, &n);
printf("m is %d and n is %d\n", m, n);
p=(int*)array(m, n);
printf("the numbers are:\n");
for (k=0; k<m*n; k++) {
printf("%d\n", p[k]);
}
return 0;
}
#include <stdlib.h>
#include <stdio.h>
char **array(int m, int n) {
int i;
char **array = malloc(m*sizeof(char*));
for (i=0; i<m; ++i) {
array[i] = malloc(n*sizeof(char));//Fixed length : like char array[m][n] (char *array[m])
scanf("%s", array[i]);//!! There is no length constraints.
printf("array[%d] is scanned and has value %s\n", i, array[i]);
}
return array;
}
int main(int argc, char*argv[]){
int m, n, k;
char **p;
scanf("%d %d", &m, &n);
printf("m is %d and n is %d\n", m, n);
p=array(m, n);
printf("the string are:\n");
for (k=0; k<m; ++k) {
printf("%s\n", p[k]);
}
return 0;
}
I'm not sure if I do this smart, but I usually allocate the pointer array and then allocate the whole memory chunk to the first item. Then I get continuous memory for the data. Like:
_array = (float**) malloc( n * sizeof ( float * ));
assert ( _array != NULL );
_array[0] = (float*) malloc( n * m * sizeof ( float ));
assert ( _array[0] != NULL );
for ( idx = 0; idx < n; idx++ )
_array[ idx ] = _array[ 0 ] + idx * m;
(float instead of int in my case. And please don't comment on the return of malloc casting, nor on the silly user of assert())