C assign some values of one struct to another - c

I am having a problem with my code. I am attempting to get some of the values from one of my structs to assign to another. Everything I find on here is about assigning the whole struct to the other.
What I am after is a drone is selected from an array of 10 drones and the details in the struct is assigned to a new member of the delivery_info struct so it can be formatted on the screen in a table.
Currently is not assigning the values from the drone struct to the delivery as intended
I have attached what I have at the moment.
void drone_delivery(Delivery *delivery_info, Drone *drones, float x1, float x2, float y1, float y2, int total, float item_weight, int*totalD){
totalD = realloc(totalD, sizeof(delivery_info) * (*totalD+1));
float cDistance = sqrt((pow(x2-x1,2) ) + (pow(y2-y1,2)));
printf("%4.2f\n", cDistance);
int i;
for ( i = 0; i < total; i++)
if (drones[i].maxDist >= cDistance && drones[i].loadCapacity >= item_weight) {
delivery_info[i].droneNumber = drones[i].droneNumber;
strcpy(drones[i].droneName, delivery_info[i].droneName);
delivery_info[i].maxDist = drones[i].maxDist;
delivery_info[i].loadCapacity = drones[i].loadCapacity;
delivery_info[i].x1=x1;
delivery_info[i].y1=y1;
delivery_info[i].x2= x2;
delivery_info[i].y2 = y2;
}
print_delivery_info(delivery_info[i]);
*totalD+=1;
}

Related

C programming, doing multiple calculations in one function

Is it possible to create a function and do multiple calculations in that function, then create another function to print out the results of the calculations... I know a function can only return one value.
There are several ways to return multiple values. One way is to "package" them as a struct:
typedef struct
{
int x;
float y;
} Result;
Result add2( int x1, int x2, float y1, float y2)
{
Result r;
r.x = x1 + x2;
r.y = y1 + y2;
return r;
}
Another way to do it is to use parameters as your outputs:
void add2( int x1, int x2, float y1, float y2, int* x, float* y)
{
*x = x1 + x2;
*y = y1 + y2;
}
You could also do combinations of these.
One return value is for wimps! Simply define the function as
struct retval { int i; double d; size_t z; } func(void);
(replacing the contents of the struct and the parameters as applicable).
Be careful when doing this, though. In spite of what I said up top, in general there is no need for multiple returns.
You can create a struct with all the things ​​you are interested in, alloc it on heap, edit it inside a function, return the same struct that you have edited and at the end free the memory.
Alternatively, you can also pass the pointer and at the end free the memory.
Example:
typedef struct date_test {
int year;
int month;
int day;
} Date;
With this you create a structure that will contain 3 int values: year, month and day.
Alloc it on heap and check for errors:
Date *test = malloc(sizeof(Date));
if (test == NULL) {
perror("Malloc");
exit(EXIT_FAILURE);
}
Edit it inside a function and return the struct, example:
Date* test_f(Date* test)
{
test->year = 2017;
test->month = 05;
test->day = 29;
return test;
}
Then free the allocated memory:
free(test);

C Code for numerical integration works on one computer but blows up on another [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I have written a code for a simple pendulum with numerical integration using rk4 method. Here's an image of expected result.
It works on my laptop, running Ubuntu 14.04, 64 bit, (it gives a sine wave as the result), but doesn't work on my PC, which runs Debian 8 and is also 64 bit.
Here's an image of the wrong plot.
Any reason why this would be happening?
Here's the code:
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
int N = 2;
float h = 0.001;
struct t_y_couple {
float t;
float *y;
};
struct t_y_couple integrator_rk4(float dt, float t, float *p1);
void oscnetwork_opt(float t, float *y, float *dydt);
int main(void) {
/* initializations*/
struct t_y_couple t_y;
int i, iter, j;
// time span for which to run simulation
int tspan = 20;
// total number of time iterations = tspan*step_size
int tot_time = (int)ceil(tspan / h);
// Time array
float T[tot_time];
// pointer definitions
float *p, *q;
// vector to hold values for each differential variable for all time
// iterations
float Y[tot_time][2];
// N = total number of coupled differential equations to solve
// initial conditions vector for time = 0
Y[0][0] = 0;
Y[0][1] = 3.14;
// set the time array
T[0] = 0;
// This loop calls the RK4 code
for (i = 0; i < tot_time - 1; i++) {
p = &Y[i][0]; // current time
q = &Y[i + 1][0]; // next time step
// printf("\n\n");
// for (j=0;j<N;j++)
// call the RK4 integrator with current time value, and current
// values of voltage
t_y = integrator_rk4(h, T[i], p);
// Return the time output of integrator into the next iteration of time
T[i + 1] = t_y.t;
// copy the output of the integrator into the next iteration of voltage
q = memcpy(q, t_y.y, (2) * sizeof(float));
printf("%f ", T[i + 1]);
for (iter = 0; iter < N; iter++)
printf("%f ", *(p + iter));
printf("\n");
}
return 0;
}
struct t_y_couple integrator_rk4(float dt, float t, float y[2]) {
// initialize all the pointers
float y1[2], y2[2], y3[2], yout[2];
float tout, dt_half;
float k1[2], k2[2], k3[2], k4[2];
// initialize iterator
int i;
struct t_y_couple ty1;
tout = t + dt;
dt_half = 0.5 * dt;
float addition[2];
// return the differential array into k1
oscnetwork_opt(t, y, k1);
// multiply the array k1 by dt_half
for (i = 0; i < 2; i++)
y1[i] = y[i] + (k1[i]) * dt_half;
// add k1 to each element of the array y
// do the same thing 3 times
oscnetwork_opt(t + dt_half, y1, k2);
for (i = 0; i < 2; i++)
y2[i] = y[i] + (k2[i]) * dt_half;
oscnetwork_opt(t + dt_half, y2, k3);
for (i = 0; i < 2; i++)
y3[i] = y[i] + (k3[i]) * dt_half;
oscnetwork_opt(tout, y3, k4);
// Make the final additions with k1,k2,k3 and k4 according to the RK4 code
for (i = 0; i < 2; i++) {
addition[i] = ((k1[i]) + (k2[i]) * 2 + (k3[i]) * 2 + (k4[i])) * dt / 6;
}
// add this to the original array
for (i = 0; i < 2; i++)
yout[i] = y[i] + addition[i];
// return a struct with the current time and the updated voltage array
ty1.t = tout;
ty1.y = yout;
return ty1;
}
// function to return the vector with coupled differential variables for each
// time iteration
void oscnetwork_opt(float t, float y[2], float *dydt) {
int i;
dydt[0] = y[1];
dydt[1] = -(1) * sin(y[0]);
}
You have a problem of lifetime with your variable yout in integrator_rk4(). You assign address of yout to ty1.y but you use it outside this function. This is undefined behavior.
quick fix:
struct t_y_couple {
float t;
float y[2];
};
struct t_y_couple integrator_rk4(float dt, float t, float y[2]) {
float y1[2], y2[2], y3[2], yout[2];
// ...
ty1.t = tout;
ty1.y[0] = yout[0];
ty1.y[1] = yout[1];
return ty1;
}
You have a lot of useless allocation and you made "spaghetti code" with your global variable. You should not cast the return of malloc.

to write a function that tests whether a Point is in a Rectangle

the question is as follows:
write and test a program with the following features.
Firstly, defines a new structured type called Point, is represented with floats for the x and y values
. Also, define a new structured type called Rectangle, which has sides parallel to the x-axis and yaxis, allowing you to represent the rectangle with the bottom_left and top_right Points.
Next write a function that computes and returns the area of a Rectangle, based upon the Rectangle parameter passed into the function.
Avoid pass by value, ensure the function exhibits pass by reference behaviour
Ensure the function returns the appropriate type of data
Next write a function that tests whether a Point is in a Rectangle. This function should take in two parameters by reference, the Point and the Rectangle to test. The function must return an integer value of one if the point is inside the rectangle, otherwise it should return zero. Write a main function, with appropriate local variables as test data to then use on the two functions above
#include <stdio.h>
struct Point
{
float x;
float y;
};
struct Rectangle
{
struct Point lb; // left below point
struct Point ru; // right upper point
};
float getArea(struct Rectangle r)
{
return (r.ru.x - r.lb.x)*(r.ru.y - r.lb.y);
}
void setValue(struct Point* p, float x, float y)
{
p->x = x;
p->y = y;
}
void setValueP(struct Rectangle* r, struct Point* lb, struct Point* ru)
{
r->lb = *lb;
r->ru = *ru;
}
void setValueR(struct Rectangle* r, float x1, float y1, float x2, float y2)
{
r->lb.x = x1;
r->lb.y = y1;
r->ru.x = x2;
r->ru.y = y2;
}
int contains(struct Rectangle r, struct Point p)
{
if((p.x > r.lb.x && p.x && p.x < r.ru.x) && (p.y > r.lb.y && p.y && p.y < r.ru.y))
return 1;
return 0;
}
int main()
{
struct Rectangle r;
setValueR(&r, 1, 2, 6, 8);
printf("%f\n", getArea(r));
struct Point p1;
setValue(&p1, 4, 5);
struct Point p2;
setValue(&p2, 4, 1);
if(contains(r, p1))
printf("inside the Rectangle\n");
else
printf("outside the Rectangle\n");
if(contains(r, p2))
printf("inside the Rectangle\n");
else
printf("outside the Rectangle\n");
}
Make sure you compile c++, those errors look like c++ code compiling with c compiler
i need it to be a c programming code, could you please help me?
The C language does not have 'reference' parameters and does not have 'classes' and does not have the concept of 'this'.
The code needs to be changed to not use references not classes nor 'this'.
You could start with changing:
struct Point
{
float x;
float y;
Point(float x, float y) : x(x), y(y)
{}
Point()
{}
};
to this:
struct Point
{
float x;
float y;
};
Then, need to include the 'struct' modifier when referencing 'Point' as there is no 'Point' class but there is a 'Point' struct.
So change this:
struct Rectangle
{
Point lb; // left below point
Point ru; // right upper point
...
to this:
struct Rectangle
{
struct Point lb; // left below point
struct Point ru; // right upper point
};
The setValue() function is using references for the parameters and using the C++ 'this' to indicate the current object:
void setValue(Point& lb, Point& ru)
{
this->lb = lb;
this->ru = ru;
}
However, C does not have the 'this' nor 'references'. To write it for C, use:
void setValue( struct rectangle *pRect, struct Point *pLB, struct Point *pRU)
{
pRect->lb.x = pLB->x;
pRect->lb.y = pLB->y;
pRect->ru.x = pRU->x;
pRect->ru.y = pRU->y;
} // end function: setValue
similar considerations pertain for the rest of the posted code.

Returning an array of structs from a function - C programming

So I'm trying to write a function that will return an array of several values. At the moment, it is running correctly but only outputting the final calculated value. How would I make it so the output includes all calculated values?
My code looks like this:
//Practice to output an array of structs
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
struct boat_params {
double V, Uc, Vc;
};
struct boat_params submerged_volume(double L1, double L2, double Lavg, double H) {
struct boat_params volume;
double V_sub, Uc_sub, Vc_sub;
V_sub = 0;
//Boat description
double C, delta;
double theta, theta_rad, theta_min, theta_min2, theta_lim, theta_lim2, theta_lim_deg;
double Ug1, Ug2, Vg1, Vg2, V1, V2;
double pi;
pi = 4*atan(1);
C = sqrt(L1*L1 + L2*L2);
delta = acos(L1/C);
theta_lim = asin(H/L1);
theta_lim_deg = (theta_lim/pi) * 180.0;
theta_min = asin(H/C) - delta;
theta_min2 = 0;
//Calculating the submerged volume and centre of gravity for each different angle
for (theta = 0; theta <= 10; theta ++) {
//**Note: I've taken out the actual calculations of V_sub, Uc_sub, and Vc_sub for brevity**
volume.V = V_sub;
volume.Uc = Uc_sub;
volume.Vc = Vc_sub;
}
return volume;
}
int main () {
double L1, L2, Lavg, H;
struct boat_params volume;
L1 = 17.6;
L2 = 3;
Lavg = 4;
H = 4.5;
volume = submerged_volume(L1, L2, Lavg, H);
printf("V = %lf\nUc = %lf\nVc = %lf\n", volume.V, volume.Uc, volume.Vc);
return 0;
}
I can get it to correctly output the last calculated value (for theta = 10) but that's the only value I'm getting. How would I calculate V_sub, Uc_sub, and Vc_sub for each theta value? and output each value. I'm assuming this means turning the struct into an array and filling each element of the array with values of the struct for that theta but I don't know how to do this!
I really appreciate any help and thank you in advance.
Also: If possible I'd like to avoid pointers but understand this may not be possible! I'm still very new and not good at using them!
You are quite right, you will need to have an array for that. If the number of elements in the array is constant, you could also create a struct that contains exactly that number elements, but please don't do that.
To operate on arrays you will - unfortunately - need pointers. A very common way to do this in C is not to return a pointer, but pass a 'result' pointer in. This means that it will be up to the user of the function to allocate space and free it, he can also use the syntax for arrays. In your code it seems that the number of values is constant, this makes the aforementioned solution possible. Alternatively you could allocate space on the heap (using malloc) and return a pointer, but that means the user needs to free memory he never allocated, counter intuitive and might result in memory leaks if he forgets to do so. Consider the following solution:
void submerged_volume(double L1, double L2, double Lavg, double H, struct boat_params *result) {
// your calculations here
for (theta = 0; theta <= 10; theta ++) {
(result+theta)->V = V_sub;
(result+theta)->Uc = Uc_sub;
(result+theta)->Vc = Vc_sub;
}
}
// somewhere in your code where you want to use your function
struct boat_params values[11];
unsigned char i = 0;
submerged_values(/* parameters */, values);
for (; i <= 10; ++i) {
printf("V = %lf\nUc = %lf\nVc = %lf\n", values[i].V, values[i].Uc, values[i].Vc);
}
Try this, just add your logic to the loop and maths:
#include <stdio.h>
#include <stdlib.h>
#define ARRSIZE 100
typedef struct boat_params {
double V, Uc, Vc;
} Volume;
struct boat_params submerged_volume(double L1, double L2, double Lavg, double H, Volume *volumes[]) {
double theta;
int i = 0; /* only example, change as needed */
Volume *p;
for (theta = 0; theta <= 10; theta ++) {
p = malloc(sizeof(* p));
if (p == NULL) {
printf("malloc failed to allocate a new space");
exit(0);
}
p->V = 1; //V_sub;
p->Uc = 2; //Uc_sub;
p->Vc = 3; //Vc_sub;
volumes[i] = p;
i++;
}
}
int main () {
double L1, L2, Lavg, H;
L1 = 17.6;
L2 = 3;
Lavg = 4;
H = 4.5;
Volume *volumes[ARRSIZE];
submerged_volume(L1, L2, Lavg, H, volumes);
printf("V = %lf\nUc = %lf\nVc = %lf\n", volumes[0]->V, volumes[0]->Uc, volumes[0]->Vc); /* first element for example */
return 0;
}
If you don't know the size of the volumes array in advance, you should consider using linked list.

Initializating struct error: 'theGrid' being used without being initialized

I am trying to create a 3d grid for my OpenCl/GL fluid. The problem Im having is that for some reason the my grid initialization function does not work properly. Here is my *.h, *.c setup and (at the end) call in main:
(grid.h):
#if RunGPU
#define make_float3(x,y,z) (float3)(x,y,z)
#define make_int3(i,j,k) (int3)(i,j,k)
#else
typedef struct i3{
int i,j,k;
} int3;
typedef struct f3{
float x,y,z;
} float3;
#define __global
#define make_float3(x,y,z) {x , y , z}
#define make_int3(x,y,z) {x , y ,z}
#endif
typedef struct grid3 * grid3_t; // u,v,w
typedef struct grid * grid_t; // p
struct grid3 {
__global float3* values_;
__global float * H_;
__global float * h_;
int dimx_;
int dimy_;
int dimz_;
} ;
struct grid {
__global float * values_;
int dimx_;
int dimy_;
int dimz_;
};
void grid3_init(grid3_t grid,__global float3* vel,__global float* H,__global float *h, int X, int Y, int Z);
(grid.c):
void grid3_init(grid3_t grid,__global float3* val,__global float* H,__global float *h, int X, int Y, int Z){
grid->values_ = val;
grid->H_ = H;
grid->h_ = h;
grid->dimx_ = X;
grid->dimy_ = Y;
grid->dimz_ = Z;
}
In main im initializing my grid like so:
int main(int argc, char** argv)
{
const int size3d = Bx*(By+2)*Bz;
const int size2d = Bx*Bz;
float3 * velocities = (float3*)malloc(size3d*sizeof(float3));
float * H = (float*)malloc(size2d*sizeof(float));
float * h = (float*)malloc(size2d*sizeof(float));
for(int i = 0; i < size3d; i++){
float3 tmp = make_float3(0.f,0.f,0.f);
velocities[i] = tmp;
if(i < size2d){
H[i] = 1;
h[i] = 2;
}
}
grid3_t theGrid;
grid3_init(theGrid, velocities, H, h, Bx, By, Bz); // <- ERROR OCCURS HERE
}
The error im getting is during runtime - "Run-Time Check Failure #3 - The variable 'theGrid' is being used without being initialized". But thats precisely the job of grid3_init?
As im trying to write code to work for both Host and GPU I have to sacrifice the use of classes and work strictly with structs - which I have less experience with.
At this point I dont really know what to google either, I appriciate any help i can get.
struct grid3 theGrid;
grid3_init(&theGrid, velocities, H, h, Bx, By, Bz);
You need to create grid3 instance and pass its pointer to grid3_init. Your existing code just uses uninitialized pointer.

Resources