In C++ we have structures which have a constructor and the destructor. It makes life much easier especially when it going to have the pointers, therefore dynamically allocated memory in the structure. You can even use std::shared_pointer library to deal with the pointers.
class A{
private:
int size;
double* stack;
public:
A(int size) : this->size(size){}
~A(){free(stack);}
};
But my maths lecturer doesn't like C++ and prefers everything in C. So I had to use C instead and came up with the following structure:
typedef struct vectorOfDoubles{
double* stack;
int size;
} vector;
I made up function that calculate the median of the vector of doubles.
double median_(const vector* v) {
vector n; // creates vector class object
n.stack = (double*)malloc(sizeof(double)*(n.size = v->size)); // takes double ptr and allocates the right amount of memory for it
memcpy(n.stack, v->stack, sizeof(double)*n.size); // copies the array of doubles.
sort(&n); // sorts the array of doubles
if(v->size%2) // checks for odd size
return n.stack[(v->size/2+1)]; // return median for odd size
else
return (n.stack[(v->size/2)]+n.stack[(v->size/2+1)])/2; // return median for even size
}
As an example of the bad practices I didn't free the memory. When the function returns its value it destructs the local variables and structures. But my structure has a pointer that holds the allocated memory. Unlikely after some research on the internet I didn't find any good destruction method solution for these situations.
My question is how the old-school C programmers dealt with those situations when they want to free the pointers in the structure but they do not have the destructor for structure that would execute itself to do a certain job?
A simple pointer needs a *alloc()
and lastly a free()
.
A structure with dynamic fields deserves a crafted vector_alloc()
and vector_free()
.
An old school flavored result:
// Return non-0 on error
int vector_alloc(vector *ptr, size_t size) {
assert(ptr);
ptr->stack = calloc(size, sizeof *(ptr->stack));
if (ptr->stack) {
ptr->size = size;
return 0;
}
ptr->size = 0;
return 1;
}
void vector_free(vector *ptr) {
assert(ptr);
free(ptr->stack);
ptr->stack = NULL;
ptr->size = 0;
}
double median_(const vector* v) {
vector n;
if (vector_alloc(&n, v->size)) return 0.0/0.0;
memcpy(n, v->stack, sizeof *n->stack *n.size);
sort(&n);
double y;
if(v->size%2)
y = n.stack[(v->size/2+1)];
else
y = (n.stack[(v->size/2)]+n.stack[(v->size/2+1)])/2;
vector_free(&n);
return y;
}