C programming: struct of complex numbers - c

I have an array of complex numbers and want to add a new complex number at the very first postion of the array.
I have a struct and a function which enters a new complex number at the first position of the array.
I have a struct which holds complex numbers
struct Complex
{
float imag;
float real;
};
I also have a function which is creating an instance of such a complex number on the heap
struct Complex* instanceOfComplex(float a, float b)
{
struct Complex* complex = malloc(sizeof(struct Complex));
if(complex == NULL)
{
return NULL; // out of memory
}
complex->imag = a;
complex->real = b;
return complex;
}
Finally I have a function which should place a new complex number at the very first position of an array of complex numbers
int attach(struct Complex *complexArray, struct Complex complex, int length)
{
int i;
for(i = length; length > 0; i--)
{
complexArray[i] = complexArray[i - 1];
}
complexArray[i] = complex;
length++;
return length;
}
The main function looks like this
int main()
{
float a = 3.6;
float b = 6.8;
struct Complex* complex = instanceOfComplex(a, b);
printf("%f %f\n", complex->imag, complex->real);
int length = 4;
struct Complex* complexArray = malloc(sizeof(length + 1) * sizeof(struct Complex));
complexArray[0] = *instanceOfComplex(8.2, 9.3);
complexArray[1] = *instanceOfComplex(7.1, 4.6);
complexArray[2] = *instanceOfComplex(0.1, 2.7);
complexArray[3] = *instanceOfComplex(5.6, 1.9);
attach(complexArray, *complex, length);
}
So finally the array should contain 5 elements of complex numbers where the new complex number is at position complexArray[0] and the other 4 elements are the following elements.
The problem is in the main function because all elements are holding (8.2, 9.3). Could someone please tell me, whats wrong here?

You are allocating memory for a new instance in instanceOfComplex and you return that (i.e. you return a pointer to the newly allocated memory).
In your main you dereference the pointer and assign the values to the array element.
You are loosing memory. Eiter allocate in main an array of pointers to complex, or have a local variable in instanceOfComplex that you return by value.
As user Yakov Dan says in his answer, you wrongly allocate the memory in main which probably causes your error.

When you allocate memory for your array, it's wrong to say sizeof(length+1).
Instead, that line should be:
struct Complex* complexArray = malloc((length + 1) * sizeof(struct Complex));

Related

Sorting an array of structures by a non-member of the struct

Person is a struct that contains 5 char arrays and nothing else.
Score is a float type number that I obtained from a function that uses some of Person fields to calculate it.
I don't wanna add score as a field in the struct Person for complicated reasons.
The goal is to print Person's information (fields) based on how high the score is (from lowest to highest), in order to do that I made this struct to try to connect the score to its corresponding person.
typedef struct PersonWithAScore {
Person* P;
float score;
};
(also, is creating that struct even
the right thing to do? )
PersonWithAScore *PersonScores = (PersonWithAScore*)malloc(number_of_scores*sizeof(PersonWithAScore));
// a for loop is happening here, so I can get all my scores and person(s) in that table, so that I start sorting them
PersonScores[i].Person = &query; // query is a Person type
PersonScores[i].Score = match; // match is what the score function returns
.
.
.
// that is just a incomplete implementation I tried, you can just skip through and just read after the code
void swap(float *xp, float *yp) // used in bubblesort
{
float temp = *xp;
*xp = *yp;
*yp = temp;
}
void BubbleSort(PersonWithAScore* PWS, int n) //n = number of scores
{ // void type? I might need to return an array (sorted)
PersonWithAScore* Temp = PWS;
int i, j;
for (i = 0; i < n-1; i++)
for (j = 0; j < n-i-1; j++) // m not so sure it's working, I didn't get to test it
if (PWS[j].score > PWS[j+1].score)
swap(&PWS[j].score, &PWS[j+1].score);
return 0;
}
So after that, I'm hoping to get a sorted array of scores (what initially was PersonScores[]) .
Optimally, I would want to go through the array while I'm printing out Person's information that are associated to each score, that is my first concern.
My second concern, is I'm not sure what sorting is proper in a big database (m currently working with a static database that contains a 100 of Person)
is it better to implement a quicksort algorithm in that case?
I figured it takes a lot of memory, but it is significantly faster than the bubble sort,
I'm trying to get a good balance of both speed and minimizing memory usage. Any ideas ?
You can use qsort() to sort the array of structures and recompute the scores on the fly in the comparison function:
float computePersonScore(Person *p) {
/* compute the score from the person's data */
...
}
int compare_scores(const void *e1, const void *e2) {
float f1 = computePersonScore(e1);
float f2 = computePersonScore(e2);
return (f1 > f2) - (f1 < f2);
}
...
Person array[n];
...
qsort(array, n, sizeof(*array), compare_scores);
...
If computePersonScore() needs a second argument, you can use qsort_r if your system supports it:
float computePersonScore(Person *p, Person *ref) {
/* compute the score from the person's data */
...
}
int compare_scores(const void *e1, const void *e2, void *opaque) {
float f1 = computePersonScore(e1, opaque);
float f2 = computePersonScore(e2, opaque);
return (f1 > f2) - (f1 < f2);
}
...
Person array[n];
Person *reference = ...;
...
qsort_r(array, n, sizeof(*array), compare_scores, reference);
...

Setting the value of one vector (array) to that of another through reference

Essentially I'm learning C code and at the moment for an assignment, I have to create a 3-dimensional space in the universe with any amount of little planets in this space, interacting through gravity.
At this point, I'm trying to set vector A (bodies[i].position), using the vector P ({1,2,3}) as seen below. Although when the code runs, it only sets the first value of the vector A to the first value of P - the rest remain as 0.
the call for VectorSet is in the main function (along with the array p), I've just put it in this format for ease.
typedef struct {
double vector[VECTOR_DIM];
} Vector;
typedef struct {
double mass;
Vector position;
Vector velocity;
Vector accel;
float colour[3];
} Object;
p[VECTOR_DIM] = {1,2,3};
VectorSet(&bodies[1].position, p);
void VectorSet(Vector *a, double vec[]) {
int i;
for (i = 0; i < VECTOR_DIM; i++) {
*(double *)(a + 8 * i) = *(double *)(vec + 8 * i);
}
}
Remove 8 from the pointer arithmetics and leave only i

Passing list to a function to fill the list with variable number of members in C

I have written code to generate a list of (x, y, z) coordinates of a given length. The code functions if I generate this list in a main function, but passing a pointer to the list into a fill_xyz_list function produces a runtime error. Presumably there is an issue with dynamic memory allocation or pointers, but I can't find it!
What is the correct way to do this?
Background:
I am trying to generate a walk cycle trajectory for a robotic leg, consisting of a finite list of (x, y, z) coordinates. As the trajectory resolution is dynamic, the list is of unknown length.
The following code produces a runtime error:
#include <stdio.h>
#include <stdlib.h>
// core data structure
struct Point
{
float x;
float y;
float z;
};
// function that allocates space for our array and fills it with dummy values
void fill_xyz_list(struct Point **xyz_list_ptr, int list_size)
{
// allocate memory for 100 Point structs
*xyz_list_ptr = realloc(*xyz_list_ptr, sizeof(struct Point)*list_size);
// set values for each member
int i;
for (i=0; i<list_size; i++)
{
xyz_list_ptr[i]->x = i + 0.1;
xyz_list_ptr[i]->y = i + 0.2;
xyz_list_ptr[i]->z = i + 0.3;
}
}
int main()
{
struct Point *xyz_list = NULL; // our array of (x, y, z)
int list_size; // our array size
int i;
// set list size
list_size = 10;
// fill xyz_list array with dummy values
fill_xyz_list(&xyz_list, list_size);
// print all members
for (i=0; i<list_size; i++)
{
printf("xyz_list[%d]: x=%.2f, y=%.2f, z=%.2f\n", i, xyz_list[i].x, xyz_list[i].y, xyz_list[i].z);
}
return 0;
}
This line
xyz_list_ptr[i]->x = i + 0.1;
should be
(*xyz_list_ptr)[i].x = i + 0.1;
Otherwise you are interpreting xyz_list_ptr as an array of pointers instead of interpreting it as a pointer to an array, which it really is.
Demo.
Note: Assigning realloc back to the pointer being reallocated could lead to memory leaks. You should assign it to a temporary, check it for NULL, and only then assign the temporary to the original pointer:
struct Point *tmp = realloc(*xyz_list_ptr, sizeof(struct Point)*list_size);
if (!tmp) {
... // deal with allocation failure
... // exit the function
}
*xyz_list_ptr = tmp;

Variable array size in c

I'm trying to declare arrays with a variable size, given by user input.
So far I have something like this:
typedef struct _object{
int rowsAmount;
int columsAmount;
int* rows;
int* colums;
} object;
object* newObject(int ra, int ca){
object* o = malloc(sizeof(object));
o->rowsAmount = ra;
o->columsAmount = ca;
o->rows = [ra];
o->colums = [ca];
return o;
}
int main(){
newObject(3,4);
}
I expected this wouldn't work, but I want something like this, and I don't know how to do it.
It looks like you're basically implementing a dynamic Matrix object here. You want something like:
typedef struct _object{
int rowsAmount;
int columsAmount;
int* matrix;
int** rows;
} object;
object* newObject(int ra, int ca){
object* o = malloc(sizeof(object));
o->rowsAmount = ra;
o->columsAmount = ca;
o->matrix = malloc(ra * ca * sizeof(int));
o->rows = malloc(ra * sizeof(int*));
for (size_t i = 0; i != ra; ++i) o->rows[i] = o->matrix + (i * ca);
return o;
}
You should also create a destructor function destroyObject, which similarly frees all the memory allocated for o and o->matrix.
Edit:
However, your comment that:
"I'm just trying to learn c, this is only about the setting the size.
I just happened to try it with 2 arrays"
...makes this question somewhat confusing, because it indicates you are not, in fact, trying to create a matrix (2D array) despite your use of "row"/"column" terminology here, but that you simply want to understand how to dynamically allocate arrays in C.
If that's the case, an array in C is dynamically allocated using a pointer variable and malloc:
size_t array_size = 10; /* can be provided by user input */
int* array = malloc(sizeof(int) * array_size);
And then later, the dynamically-allocated array must be freed once you are finished working with it:
free(array);
To dynamically allocate a 2d array of data in C:
Allocate the memory for the entire data. That memory is pointed to by arrayData.
Allocate an 1D Array of pointers one for each row
Point those pointers to the memory address corresponding each row
Code:
int *arrayData = malloc(sizeof(int) * rows * columns);
int **array = malloc(sizeof(int*) * rows);
for(int i=0; i < rows;++i){
array[i] = arrayData + i * columns;
}
You can now access the memory as array[row][col].
You can create a array with size input from user with out a structure.
int *array1;
int size;
// get input from user
array1 = malloc(sizeof(int)*size);
// do your stuff
free(array1);
if you want a 2D array,
int **array2;
int row, col;
int i;
array2 = malloc(sizeof(int*)*row);
for(i=0;i<row;++i)
array2[i] = malloc(sizeof(int)*col);
//use the array
for(i=0;i<row;++i)
free(array2[i]);
free(array2);
if you really need a structure array, then allocate memory for it in your newObject() function
typedef struct _object{
int rowsAmount;
int columsAmount;
int** array;
//int* colums;
} object;
object* newObject(int ra, int ca){
int i;
object* o = malloc(sizeof(object));
o->rowsAmount = ra;
o->columsAmount = ca;
o->array = malloc(sizeof(int*)*ra);
for(i=0;i<ra;i++)
o-<array[i]=malloc(sizeof(int)*ca);
return o;
}
int main(){
newObject(3,4);
}
I think that quite often people use dynamic memory allocation when scoped variables can be used instead. For example, array sized from user's input can be allocated on stack without using malloc/free:
int array_size;
scanf("%d", &array_size);
if (array_size > 0) {
/* Allocate array on stack */
float array[array_size];
/* ... do smth with array ... */
}
/* Out of scope, no need to free array */
Of course if your data block is huge, heap memory is a must, but for small allocations scopes are just fine.
Easiest way is to use boost::multi_array
Not only will you get any number of dimensions, it's also stored very efficiently as a single contiguous block of memory rather than n dimensional array.
CPU's are designed to traverse arrays quickly, and you could potentially utilise caching/prefetch/pipelining features of the compiler using this.
Eg
// 2 dimensions
int xDim;
int yDim;
cin >> xDim; // From user..
cin >> yDim;
// Initialise array
boost::multi_array<int,2> my2dgrid(boost::extents[xDim][yDim]);
// Iterate through rows/colums
for(int j = 0 ; j < yDim-1; j++) { // Row traversal
for(int i = 0 ; i < xDim-1; i++) { // Column traversal
int value = grid[j][i]; // Get a value
grid[j][i] = 123; // set a value
// Do something...
}
#include <stdio.h>
#include <stdlib.h>
typedef struct _object{
int rowsAmount;
int columsAmount;
int **rows;
// int* colums;
} object;
object* newObject(int ra, int ca){
int r;
object* o = malloc(sizeof(object));
o->rowsAmount = ra;
o->columsAmount = ca;
o->rows = (int **)malloc(ra*sizeof(int *));
for(r=0;r<ra;++r)
o->rows[r] = (int*)malloc(ca*sizeof(int));
return o;
}
int main(){
object *obj= newObject(3,4);
obj->rows[2][3]=5;
return 0;
}

Pointer to 2D struct array C

I have a certain struct structXand a 2D array which holds these kind of structs.
I want to be able to save a pointer to that 2D struct and iterate over it
in a dynamic way, meaning, the pointer can hold any structX and iterate.
Example in general lines:
struct structX *ptr = NULL;
...
if(i == OK)
{
ptr = General_struct_which_holds_others->ptr1;
}
else if(i ==NOT_OK)
{
ptr = General_struct_which_holds_others->ptr2;
}
Now the iteration:
if(ptr[x][y] == OK) <----Error, subscripted value is neither array nor pointer
{
...
}
I hope i'm understood, As i was saying this is very general.
How can the iteration be made? meaning not getting errors?
Thanks!
Two problem I can noticce in your code if(ptr[x][y] == OK)
(1):
ptr is pointer to structure (single *) you can't use double indices [][] so error at if(ptr[x][y] == OK)
error, subscripted value is neither array nor pointer because of ptr[][]
(2):
error: used struct type value where scalar is required means if(struct are not allow).
if(should be a scalar value )
scalar value means can be convert into 0/1.
Pointer to 2D struct array C
struct structX matrix2D[ROW][COL];
its pointer
struct structX (*ptr2D)[ROW][COL];
ptr2D = &matrix2D;
ok, access you array structure like this:
struct structX i;
(*ptr2D)[r][c] = i;
If you want to pass in an function do like:
void to(struct structX* ptr2D[][COL]){
struct structX i;
ptr2D[][COL] = i;
}
void from(){
struct structX matrix2D[ROW][COL];
to(matrix2D);
}
Just to make you sure I written a simple code shows how to work with ptr2D. Hope you find it helpful:
#include<stdio.h>
#define ROW 10
#define COL 5
typedef struct {
int a;
char b;
} structX;
void to(structX ptr2D[][COL], int r, int c){
printf("in to: %d %c\n", ptr2D[r][c].a, ptr2D[r][c].b);
}
int main(){
structX matrix[ROW][COL];
structX (*ptr2D)[ROW][COL];
ptr2D = &matrix;
structX i;
i.a = 5;
i.b = 'a';
int r = 3;
int c = 2;
(*ptr2D)[r][c] = i;
printf("%d %c\n", (*ptr2D)[r][c].a, (*ptr2D)[r][c].b);
to(matrix, r, c);
}
And its working, Output:
5 a
in to: 5 a
EDIT
I wanted to show two tricks but now I think I should provide a uniform method(as you commented):
So here is the code:
#include<stdio.h>
#define ROW 10
#define COL 5
typedef struct {
int a;
char b;
} structX;
void to(structX (*ptr2D)[ROW][COL], int r, int c){
printf("in to: %d %c\n", (*ptr2D)[r][c].a, (*ptr2D)[r][c].b);
}
int main(){
structX matrix[ROW][COL];
structX (*ptr2D)[ROW][COL];
ptr2D = &matrix;
structX i;
i.a = 5;
i.b = 'a';
int r = 3;
int c = 2;
(*ptr2D)[r][c] = i;
printf("%d %c\n", (*ptr2D)[r][c].a, (*ptr2D)[r][c].b);
to(&matrix, r, c);
}
Output
5 a
in to: 5 a
EDIT:
error: used struct type value where scalar is required means if(struct are not allow).
if(should be a scalar value )
you can't do like if((*ptr2D)[r][c]);
but this is allow:
if((*ptr2D)[r][c].a == 5);
or
if((*ptr2D)[r][c].b == 'a');
or
if((*ptr2D)[r][c].a == 5 && (*ptr2D)[r][c].b == 'a');
or
structX i;
if((*ptr2D)[r][c] == i);
You might want to ready this article about multidimensional arrays. If you want to iterate over an array, you need to know how big it is (whether it is dynamic or not). If you want it to be dynamic, that means you need to allocate memory for it when it needs to grow and you need to free the old memory. You also have a problem in your question - you declare a single pointer which is null and then try to dereference it but you never allocated memory for it.
If you did allocate memory for it, you could dereference it by saying
ptr[x * ROW_WIDTH + y]
if you set ROW_WIDTH to the maximum value of y. Depending on whether you want to represent a rows major or column major array, you might use y * width instead of x * width.

Resources