I have questions about how to properly implement objects in C. 

Is the fact that I return objects from methods more prone to memory leaks than, for example, never returning an object and doing it by reference in the argument list like this?

```
extern void quaternion_get_product(Quaternion * this, Quaternion * q, Quaternion * result);

```

This way the `malloc()` call is only done in the constructor, so it is easier to control.

I am new to this kind of encapsulation in C, so I am not sure if this would be the way to solve my problem. I just want my code to be scalable, and I see that if I continue doing this, memory leaks are going to be all around, and it is going to be really hard to debug. How is it usually approached? Am I on the right track with my code?

My question is, if I have this:

```
Quaternion p = *quaternion_create(1, 0, 0, 0);
Quaternion q = *quaternion_create(1, 0, 1, 0);
Quaternion r = *quaternion_create(1, 1, 1, 0);
Quaternion s = *quaternion_create(1, 1, 1, 1);

p = *quaterion_get_product(&p, &q); // Memory leak, old p memory block is not being pointed by anyone

Quaternion t = *quaternion_get_product(&q, quaternion_get_product(&s, &r)); 

```

Memory leaks are present when nesting function calls, intermediate memory blocks are not pointed by any existing pointer, cannot call quaternion\_destroy

**Header file:**

```
#ifndef __QUATERNIONS_H_
#define __QUATERNIONS_H_

#include <stdlib.h>

typedef struct Quaternion Quaternion;

struct Quaternion {
    float w;
    float x;
    float y;
    float z;
};

extern Quaternion *quaternion_create(float nw, float nx, float ny, float nz);
extern void quaternion_destroy(Quaternion *q);
extern Quaternion *quaternion_get_product(Quaternion *this, Quaternion *q);
extern Quaternion *quaternion_get_conjugate(Quaternion *this);
extern float quaternion_get_magnitude(Quaternion *this);
extern void quaternion_normalize(Quaternion *this);
extern Quaternion *quaternion_get_normalized(Quaternion *this);
#endif

```

**Implementation file:**

```
#include "quaternion.h"
#include <math.h>

Quaternion *quaternion_create(float nw, float nx, float ny, float nz) {
    Quaternion *q = malloc(sizeof(Quaternion));

    q->w = nw;
    q->x = nx;
    q->y = ny;
    q->z = nz;
    return q;
}

void quaternion_destroy(Quaternion *q) {
    free(q);
}

Quaternion *quaternion_get_product(Quaternion *this, Quaternion *p) {
        Quaternion *return_q = quaternion_create(
            this->w * p->w - this->x * p->x - this->y * p->y - this->z * p->z,  // new w
            this->w * p->x + this->x * p->w + this->y * p->z - this->z * p->y,  // new x
            this->w * p->y - this->x * p->z + this->y * p->w + this->z * p->x,  // new y
            this->w * p->z + this->x * p->y - this->y * p->x + this->z * p->w
        );
        return return_q;
}

Quaternion *quaternion_get_conjugate(Quaternion *this)
{
        return quaternion_create(this->w, -this->x, -this->y, -this->z);
}

float quaternion_get_magnitude(Quaternion *this) {
        return sqrt(this->w * this->w + this->x * this->x + this->y * this->y + this->z * this->z);
}

void quaternion_normalize(Quaternion *this) {
        float m = quaternion_get_magnitude(this);
        this->w /= m;
        this->x /= m;
        this->y /= m;
        this->z /= m;
}

Quaternion *quaternion_get_normalized(Quaternion *this) {
        Quaternion *r = quaternion_create(this->w, this->x, this->y, this->z);
        quaternion_normalize(r);
        return r;
}

```
['https://Stackoverflow.com/questions/42019535', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/4900440/']
Actually, it can get even worse if some function has *both* side effect of updating something and return a newly constructed value. Say, who remembers that `scanf` returns a value?

Looking at [GNU Multi Precision Arithmetic Library](https://gmplib.org/) I'd suggest that the following is one reasonable solution (actually, they go even further by making memory allocation user's headache, not library's):

1. Only a constructor can create a new object. I'd also suggest that all constructors' name follow the same pattern.
2. Only a destructor can destroy an already existing object.
3. Functions take both input arguments (say, two sides of `+`) and output argument(s) (where to put the result, overriding everything that was in the object before), like this:

`mpz_add (a, a, b); /* a=a+b */`

That way you will always clearly see when objects are created/destroyed and can ensure that there are no leaks or double frees. Of course, that prevents you from "chaining" multiple operations together and makes you manually manage temporary variables for intermediate results. However, I believe you'd still have to do that manually in C, because even compiler does not know much about dynamically allocated variable's lifetime.

Actually, if we leave no. 3 and add the "library does not manage memory" clause, we will get even more error-prone solution (from library's point of view), which will require library's user to manage memory however they want. That way you also don't lock user with `malloc`/`free` memory allocation, which is kind of good thing.
Looks to me like you're calling it wrong.

You also need to check to see if malloc() returns NULL and handle that failure (such as by displaying an out of memory error message and exiting if it fails because that's non-recoverable generally).

**UPDATE:**

Since YOU need to free your intermediate result you have to take more action to retain the pointer.

**UPDATE 2**

@MichaelWalz approach is great. Why deal with all the allocations and pointer management if you don't need to? However, if you *do* use pointers and allocate memory you have to retain pointers and make sure you free things and pass them around/reuse them carefully. I've updated my example to handle the nested call.

**UPDATE 3**

I had to remove the &'s from the function call arguments because you're passing pointers in, which are already the address of what you want to point to. You didn't assign the output of the functions properly. Notice how the pointer assignments are different in the fixed example too.

---

```
Quaternion p = *quaternion_create(1, 0, 0, 0);
Quaternion q = *quaternion_create(1, 0, 1, 0);
Quaternion r = *quaternion_create(1, 1, 1, 0);
Quaternion s = *quaternion_create(1, 1, 1, 1);

p = *quaterion_get_product(&p, &q); // Memory leak, old p memory block is not being pointed by anyone

Quaternion t = *quaternion_get_product(&q, quaternion_get_product(&s, &r)); 

```

---

```
Quaternion *p = quaternion_create(1, 0, 0, 0);
Quaternion *q = quaternion_create(1, 0, 1, 0);
Quaternion *r = quaternion_create(1, 1, 1, 0);
Quaternion *s = quaternion_create(1, 1, 1, 1);

Quaternian *tmp = quaterion_get_product(p, q); 
quaternian_destroy(p);
p = tmp;
tmp = quaternion_get_product(s, r)
Quaternion *t = quaternion_get_product(q, tmp); 
quaternian_destroy(tmp);

```