This is not homework, just a question about my code (I'm learning C++).
I have multiple instances of the class Renderer that all use the same resource, a BMP loaded by SDL. Is this a correct way to manage a shared resource for a class? If not, what is a good one? If yes, are there better ones?
renderer.hpp
class Renderer {
public:
Renderer(SDL_Surface *target_surface, int w, int h);
Renderer(const Renderer& renderer);
~Renderer();
// ...
private:
int w, h;
SDL_Surface *target;
static SDL_Surface *blocks;
static int numinstances;
};
renderer.cpp
const char BLOCKS_FILE[] = "blocks.bmp";
SDL_Surface *Renderer::blocks = 0;
int Renderer::numinstances = 0;
Renderer::Renderer(SDL_Surface *target, int w, int h) {
numinstances++;
if (blocks == 0) {
// temporary storage for file
SDL_Surface *loadedimg = SDL_LoadBMP(BLOCKS_FILE);
if (loadedimg != NULL) {
blocks = SDL_DisplayFormat(loadedimg);
SDL_FreeSurface(loadedimg);
}
}
this->target = target;
this->w = w;
this->h = h;
}
Renderer::Renderer(const Renderer& renderer) {
numinstances++;
w = renderer.w;
h = renderer.h;
target = renderer.target;
}
Renderer::~Renderer() {
numinstances--;
if (numinstances == 0) {
SDL_FreeSurface(blocks);
blocks = 0;
}
}
Is this a correct way to manage a shared resource for a class?
Yes, strictly speaking it's a correct way. But it's one that you should walk away from as fast as you can. No, don't walk - run. And don't look back.
If not, what is a good one?
Prefer anything that resembles std::shared_ptr<> or boost::shared_ptr<>.
If yes, are there better ones?
Instead of having a static surface pointer and a static reference counter inside the class, just keep one shared_ptr for the surface there, create it once outside of the class and then pass it to the renderer constructor. Some benefits of doing so:
(Edit in bold:)
You don't need to think about who's the last owner and thus responsible for resource deletion, since shared_ptr does that for you.
Thread safety
Less code often means fewer bugs.
Related
I have a Python object referring to a C++ object.
Header:
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include <structmember.h>
typedef struct {
PyObject_HEAD
FrameBuffer frame_buffer;
} PyFrameBuffer;
extern PyTypeObject PyFrameBuffer_type;
extern PyObject* PyFrameBuffer_NEW(size_t width, size_t height);
The C++ FrameBuffer class is following:
class FrameBuffer {
public:
explicit FrameBuffer(const size_t width, const size_t height);
// ...
private:
size_t m_width;
size_t m_height;
std::vector<Pixel> m_pixels;
};
Pixel is a simple class of few plain type elements.
The PyFrameBuffer_NEW() function is following:
PyObject* PyFrameBuffer_NEW(size_t width, size_t height)
{
auto* fb = (PyFrameBuffer*) PyObject_NEW(PyFrameBuffer, &PyFrameBuffer_type);
if (fb != nullptr)
{
fb->frame_buffer = FrameBuffer(width, height);
}
return (PyObject*) fb;
}
This code crashs:
fb->frame_buffer is allocated with undefined values (fb->frame_buffer.m_pixels.size() is undefined).
During fb->frame_buffer assignment, there is a deallocation of an undefinied number of Pixel in m_pixels.
And so, it crash.
This code seems to works:
/// ...
if (fb != nullptr)
{
FrameBuffer fb_tmp(width, height);
std::memcpy(&fb->frame_buffer, &fb_tmp, sizeof(FrameBuffer));
}
// ...
But I suspect this is not the proper way to solve this issue (I suspect Pixels in fb_tmp are desallocated outside the scope.
What would the the proper way to solve this problem?
Is there a commonly known approach on how to expose complex object in CPython?
I've successfully used code similar to
typedef struct {
PyObject_HEAD
FrameBuffer *frame_buffer;
} PyFrameBuffer;
and then
if (fb != nullptr)
{
fb->frame_buffer = new FrameBuffer( ... );
}
But you have to account for deleting the object explicitly. You'll need to add a tp_dealloc() function to your PyFrameBuffer initialization that deletes the C++ FrameBuffer object:
delete fb->frame_buffer;
Also:
When you use C++ to create a Python extension module, you're linking in your code's C++ runtime libraries. If more than one module uses C++, they all have to use the exact same C++ runtime libraries.
I added a destructor to some code and it seems to be calling early and causing problems. I added a debug statement to see where it is being called and that made me even more confused. I understand that managing my own memory is not best practice but I wanted to try it out myself.
This is basically my GameObject class:
class GameObject
{
public:
int xCoord = 0, yCoord = 0, prevX, prevY;
int status = 0, weight = -1;
int id = -1;
GameObject(CommandComponent* commands,
PhysicsComponent* physics,
GraphicsComponent* graphics)
: commandComponent(commands),
physicsComponent(physics),
graphicsComponent(graphics)
{};
~GameObject()
{
std::cout << "Destructor called " << id << std::endl;
delete commandComponent;
delete physicsComponent;
delete graphicsComponent;
};
void update(World& world, int command, sf::Time dt)
{
commandComponent->update(*this, world, command);
physicsComponent->update(*this, world);
graphicsComponent->update(*this, dt);
};
void update(World& world, int command)
{
commandComponent->update(*this, world, command);
physicsComponent->update(*this, world);
};
sf::Sprite draw()
{
return *(graphicsComponent->draw());
};
void setCoords(int x, int y)
{
prevX = xCoord;
xCoord = x;
prevY = yCoord;
yCoord = y;
};
void setId(int newId)
{
id = newId;
}
private:
CommandComponent* commandComponent = NULL;
GraphicsComponent* graphicsComponent = NULL;
PhysicsComponent* physicsComponent = NULL;
};
This is the createPlayer Method:
GameObject* createPlayer(sf::Texture* text)
{
return new GameObject(new PlayerCommandComponent(), new PlayerPhysicsComponent(), new PlayerGraphicsComponent(text));
};
This is a method I invoke to add the new object to a vector based on if it is an active object or an inactive one I also add it to an array :
void World::addObject(GameObject object, int id, int type){
object.setId(id);
if (type == 0)
{
inactiveObjects.push_back(object);
}
else if (type == 1)
{
activeObjects.push_back(object);
}
}
Finally this is my test code that creates the Game Objects and calls the above function and where I see the destructors being called from:
void World::test()
{
// Player
std::cout << "Starting to create id 0\n";
addObject((*createPlayer(&(mTextures.get(Textures::PlayerCharacter)))), 0, 1);
activeObjects.at(0).setCoords(3, 3);
activeObjects.at(0).weight = 10;
std::cout << "Created id 0\n";
// Test Objects
std::cout << "Starting to create id 1\n";
addObject((*createPlayer(&(mTextures.get(Textures::PlayerCharacter)))), 1, 1);
activeObjects.at(1).setCoords(3, 4);
activeObjects.at(1).weight = 7;
std::cout << "Created id 1\n";
addObject((*createPlayer(&(mTextures.get(Textures::PlayerCharacter)))), 2, 1);
activeObjects.at(2).setCoords(5, 4);
activeObjects.at(2).weight = 2;
addObject((*createPlayer(&(mTextures.get(Textures::Enemy)))), 3, 1);
activeObjects.at(3).setCoords(6, 6);
activeObjects.at(3).weight = -1;
addObject((*createPlayer(&(mTextures.get(Textures::Enemy)))), 4, 1);
activeObjects.at(4).setCoords(1, 1);
activeObjects.at(4).weight = 0;
std::cout << "Done Creating Test Objects\n";
I guess my main question is how come the Destructors are being called? Im assuming its related to how I'm constructing the object in the createPlayer method, Perhaps it's going out of scope after I return it but I thought using the new keyword would prevent that from happening? I'm puzzled here.
Several things at play here.
GameObject* createPlayer(sf::Texture* text)
returns a dynamically allocated GameObject. This could be done better, read up on std::unique_ptr, but there is nothing strictly wrong here. I mention it mostly to point out std::unique_ptr and set up
addObject((*createPlayer(&(mTextures.get(Textures::PlayerCharacter)))), 0, 1);
because this is where thing start to go wrong. When you find code that uses new and dereferences and discards the the result, you're looking at a memory leak. You've lost the pointer to the dynamically allocated object and without the pointer it is next to impossible to find the allocation again so that you can delete it.
Storing the dereferenced object will invoke either the copy constructor or the assignment operator and at this point you need to consider The Rule of Three: If you need a to define a custom destructor, you probably need to define a custom assignment operator and a copy constructor. This is a standard example of when you need to observe the Rule of Three. What goes wrong is well-explained in the Rule of Three Link, so stop, read, and understand it before going any further. Failure to do this means the rest of this answer will be nigh-useless to you.
You cannot write good, non-trivial C++ code without a firm grip on the Rule of Three and all of its friends.
You can step around the Rule of Three here by changing
void World::addObject(GameObject object, int id, int type)
to
void World::addObject(GameObject * object, int id, int type)
and pass object by reference. This doesn't help much because
inactiveObjects.push_back(object);
is expecting an object, not a pointer.
You can change that as well, but should you? std::vector is at its absolute best when it directly contains an object. Pointers lead to pointer chasing, poor caching behaviour and ultimately suuuhhhfering. Don't store pointers unless you have a compelling reason to do so.
And if you do, manage the pointers with a std::unique_ptr beginning to end.
What I would do:
Jump straight over the Rule of Three and go to The Rule of Five.
Exterminate as many dynamically allocated variables as possible so that I don't need to do much work, if any, with point 2. This means no pointers for (or in) commandComponent, physicsComponent and graphicsComponent if possible.
Add a move constructor and move assignment operator to GameObject as well as CommandComponent, PhysicsComponent, and GraphicsComponent. Keep all resource management as close to the resource as possible. This allows you to keep higher level classes as ignorant as possible. If GraphicsComponent knows how to copy and move itself, GameObject doesn't need to know how to move it. This allows you to take advantage of The Rule of Zero, and the Rule of Zero should be what you strive for in all of your classes.
Use move semantics to get a GameObject, not a GameObject* from createPlayer down to the activeObjects and inactiveObjects vectors.
Enjoy the reduced memory management load.
I really need help on this one cause I am extremely stuck and have no idea what to do.
Edit:
A lot of you guys are saying that I need to use the debugger but let me be clear I have not used C++ for an extremely long time and I've used visual studio for a grand total of 2 weeks so I do not know all the cool stuff it can do with the debugger.
I am a student at university at the beginning of my second year who is trying to work out how to do something mostly by failing.
I AM NOT a professional coder and I don't have all the knowledge that you people have when it comes to these issues and that is why I am asking this question. I am trying my best to show my issue so yes my code contains a lot of errors as I only have a very basic understanding of a lot of C++ principles so can you please keep that in mind when commenting
I'm only posting this here because I can don't know who else to ask right now.
I have a function called world that is suppose to call my render class to draw all the objects inside of its vector to the screen.
#include "C_World.h"
C_World::C_World()
{
// creates an instance of the renderer class to render any drawable objects
C_Renderer *render = new C_Renderer;
}
C_World::~C_World()
{
delete[] render;
}
// adds an object to the world vector
void C_World::addToWorld(C_renderable* a)
{
world_list.push_back(a);
}
void C_World::World_Update()
{
render->ClearScreen();
World_Render();
}
void C_World::World_Render() {
for (int i = 0; i < 1; i++)
{
//render->DrawSprite(world_list[i]->getTexture(), world_list[i]->get_X, world_list[i]->get_Y());
render->DrawSprite(1, 1, 1);
}
}
While testing I commented out the Sprites get functions in order to check if they were causing the issue.
the renderer sprites are added to the vector list in the constructor through the create sprite function
C_Renderer::C_Renderer()
{
// test sprite: Id = 1
CreateSprite("WhiteBlock.png", 250, 250, 1);
}
I thought this might of been the issue so I had it in other functions but this didn't solve anything
Here are the Draw and create Sprite functions
// Creates a sprite that is stored in the SpriteList
// Sprites in the spriteList can be used in the drawSprite function
void C_Renderer::CreateSprite(std::string texture_name,
unsigned int Texture_Width, unsigned int Texture_height, int spriteId)
{
C_Sprite *a = new C_Sprite(texture_name,Texture_Width,
Texture_height,spriteId);
SpriteList.push_back(a);
size_t b = SpriteList.size();
HAPI.DebugText(std::to_string(b));
}
// Draws a sprite to the X and Y co-ordinates
void C_Renderer::DrawSprite(int id,int x,int y)
{
Blit(screen, _screenWidth, SpriteList[id]->get_Texture(),
SpriteList[id]->getTexture_W(), SpriteList[id]->getTexture_H(), x, y);
}
I even added some test code into the create sprite function to check to see if the sprite was being added too the vector list. It returns 1 so I assume it is.
Exception thrown: read access violation.
std::_Vector_alloc<std::_Vec_base_types<C_Sprite *,
std::allocator<C_Sprite *> > >::_Mylast(...) returned 0x8.
that is the full error that I get from the compiler
I'm really really stuck if there is anymore information you need just say and ill post it straight away
Edit 2:
#pragma once
#include <HAPI_lib.h>
#include <vector>
#include <iostream>
#include "C_renderable.h"
#include "C_Renderer.h"
class C_World
{
public:
C_World();
~C_World();
C_Renderer *render = nullptr;
void World_Update();
void addToWorld(C_renderable* a);
private:
std::vector<C_renderable*> world_list;
void C_World::World_Render();
};
#pragma once
#include <HAPI_lib.h>
#include "C_renderable.h"
#include "C_Sprite.h"
#include <vector>
class C_Renderer
{
public:
C_Renderer();
~C_Renderer();
// gets a pointer to the top left of screen
BYTE *screen = HAPI.GetScreenPointer();
void Blit(BYTE *destination, unsigned int destWidth,
BYTE *source, unsigned int sourceWidth, unsigned int sourceHeight,
int posX, int posY);
void C_Renderer::BlitBackground(BYTE *destination,
unsigned int destWidth, unsigned int destHeight, BYTE *source,
unsigned int sourceWidth, unsigned int sourceHeight);
void SetPixel(unsigned int x,
unsigned int y, HAPI_TColour col,BYTE *screen, unsigned int width);
unsigned int _screenWidth = 1750;
void CreateSprite(std::string texture_name,
unsigned int Texture_Width,unsigned int Texture_height, int spriteId);
void DrawSprite(int id, int x, int y);
void ClearScreen();
private:
std::vector<C_Sprite*> SpriteList;
};
I don't say this lightly, but the code you've shown is absolutely terrible. You need to stop and go back several levels in your understanding of C++.
In all likeliness, your crash is the result of a simple "shadowing" issue in one or more of your functions:
C_World::C_World()
{
// creates an instance of the renderer class to render any drawable objects
C_Renderer *render = new C_Renderer;
}
C_World::~C_World()
{
delete[] render;
}
There are multiple things wrong here, and you don't show the definition of C_World but if this code compiles we can deduce that it has a member render, and you have fallen into a common trap.
C_Renderer *render = new C_Renderer;
Because this line starts with a type this is a definition of a new, local variable, render. Your compiler should be warning you that this shadows the class-scope variable of the same name.
What these lines of code
C_World::C_World()
{
// creates an instance of the renderer class to render any drawable objects
C_Renderer *render = new C_Renderer;
}
do is:
. assign an undefined value to `this->render`,
. create a *local* variable `render`,
. construct a dynamic `C_Renderer` presumably on the heap,
. assign that to the *local* variable `render`,
. exit the function discarding the value of `render`.
So at this point the memory is no-longer being tracked, it has been leaked, and this->render is pointing to an undefined value.
You repeat this problem in several of your functions, assigning new results to local variables and doing nothing with them. It may not be this specific instance of the issue that's causing the problem.
Your next problem is a mismatch of new/delete vs new[]/delete[]:
C_World::~C_World()
{
delete[] render;
}
this would result in undefined behavior: this->render is undefined, and delete[] on a non-new[] allocation is undefined.
Most programmers use a naming convention that distinguishes a member variable from a local variable. Two common practices are an m_ prefix or an _ suffix for members, e.g.
class C_World
{
public:
C_Foo* m_foo; // option a
C_Renderer* render_; // option b
// ...
}
Perhaps you should consider using modern C++'s concept of smart pointers:
#include <memory>
class C_World {
// ...
std::unique_ptr<C_Renderer> render_;
// ...
};
C_World::C_World()
: render_(new C_Renderer) // initializer list
{}
But it's unclear why you are using a dynamic allocation here in the first place. It seems like an instance member would be better:
class C_World {
C_Renderer render_;
};
C_World::C_World() : render_() {}
I have two classes, in the example added Rectangle and Rectangles. The goal is to make one Rectangles object which holds references to multiple Rectangle objects.
If I change r by r.set_values(4,4) then off coarse r.area() is changed. However if I call rectangles.rects[0].area() it remains 12, and therefore is not changed.
As I understood I am making a reference of r in rectangles, however this seems to be wrong.
How to achieve this?
The code is available here
#include <iostream>
using namespace std;
class Rectangle {
int width, height;
public:
void set_values (int,int);
int area() {return width*height;}
};
void Rectangle::set_values (int x, int y) {
width = x;
height = y;
}
class Rectangles {
public:
Rectangles(int n);
void addRectangle(Rectangle* r);
Rectangle* rects;
int nRects;
};
Rectangles::Rectangles(int n) {
rects = new Rectangle[n];
nRects = 0;
}
void Rectangles::addRectangle(Rectangle* r) {
rects[nRects] = *r;
nRects++;
}
int main() {
Rectangle r;
Rectangles rectangles(5);
r.set_values(4,3);
rectangles.addRectangle(&r);
cout<<"r.area() before change:"<<r.area()<<endl;
cout<<"rectangles.rects[0].area() before change:"<<rectangles.rects[0].area()<<endl;
r.set_values(4,4);
cout<<"r.area() after change:"<<r.area()<<endl;
cout<<"rectangles.rects[0].area() after change:"<<rectangles.rects[0].area()<<endl;
return 0;
}
Output:
r.area() before change:12
rectangles.rects[0].area() before change:12
r.area() after change:16
rectangles.rects[0].area() after change:12
What is wrong with your code is your definition of Rectangles. It stores a pointer (or an array) to a Rectangle. What you want here is not an array of Rectangle's, but an array of references to Rectangle's. Here, the references shall be pointers, so you need to change this accordingly :
class Rectangles {
public:
Rectangles(int n);
void addRectangle(Rectangle* r);
// Rectangle* rects;
// What you really want :
Rectangle** rects;
int nRects;
};
But then you also need to change the implementation :
Rectangles::Rectangles(int n) {
rects = new Rectangle*[n]; // Array of pointers
nRects = 0;
}
void Rectangles::addRectangle(Rectangle* r) {
rects[nRects] = r; // r is a pointer : just store it, no dereferencing
nRects++;
}
However, this is a bad design : you should not have to use any of these : pointer to pointer (or 'raw array' of pointers), new, and a class whose only purpose is to store an array of things. This is because you already have better tools for this : smart pointers (although you do not need them here either), arrays and dynamic arrays (or vectors).
So, if I were you, this is how I would rewrite your code :
#include <iostream>
#include <vector>
class Rectangle {
public:
void setSize(int w, int h);
int area();
private:
int width, height;
};
void Rectangle::setSize(int w, int h) {
width = w;
height = h;
}
int Rectangle::area() {
return width * height;
}
int main() {
Rectangle r;
std::vector<Rectangle*> rectangles;
r.setSize(4, 3);
rectangles.push_back(&r);
std::cout << "r.area() before change : " << r.area() << std::endl
<< "rectangles[0]->area() before change : "
<< rectangles[0]->area() << std::endl;
r.setSize(4, 4);
std::cout << "r.area() after change : " << r.area() << std::endl
<< "rectangles.rects[0]->area() after change : "
<< rectangles[0]->area() << std::endl;
return 0;
}
Edit :
You might wonder why I used a raw pointer instead of a smart pointer (since I told you to avoid pointers to pointer). This is quite simple : no smart pointer would fit the matter. Let us see why.
std::unique_ptr keeps sole ownership of the object. What if you want another reference to it ? Also, if you ever destroy this smart pointer via std::vector's erase, it would also destroy your object. So if you access it afterwards, you would get some dirty error.
std::shared_ptr keeps shared ownership of the object. Sure, you can have another reference to your object, but the same thing happens if you destroy the pointer. Also, it has some overhead, and is not so easy to use correctly.
std::weak_ptr works with std::shared_ptr, nothing more to say.
A raw pointer, on the contrary, only needs you to ensure that the lifetime of the object is longer or equal to its own lifetime, so that you can always access your object via the pointer. And that is all.
Finally, here is a general rule of thumbs (that I use) :
unique_ptrs are for sole ownership
raw pointers mean whoever gave me the raw pointer guarantees the lifetime of that object to match or exceed my lifetime.
shared_ptrs are for shared ownership
weak_ptrs are for when a system wants to check if the object still exists before using it. This is rare in my code since I find it cleaner to have a system guarantee the lifetime of anything it passes it's subsystems (in which case I use a raw pointer)
class Rectangles {
public:
void addRectangle(Rectangle* r);
vector<Rectangle *> rects;
};
void Rectangles::addRectangle(Rectangle* r) {
rects.push_back(r);
}
int main() {
Rectangle r;
Rectangles rectangles;
r.set_values(4,3);
rectangles.addRectangle(&r);
cout<<"r.area() before change:"<<r.area()<<endl;
cout<<"rectangles.rects[0]->area() before change:"<<rectangles.rects[0]->area()<<endl;
r.set_values(4,4);
cout<<"r.area() after change:"<<r.area()<<endl;
cout<<"rectangles.rects[0]->area() after change:"<<rectangles.rects[0]->area()<<endl;
return 0;
}
Output:
r.area() before change:12
rectangles.rects[0]->area() before change:12
r.area() after change:16
rectangles.rects[0]->area() after change:16
I'm making a game with SDL that used libconfig to read some settings from a file. The problem is that I made a class called ClipList that contains a std::vector<SDL_Rect> to store the settings but when trying to add SDL_Rect objects to the vector, for some reason push_back does nothing and I end up with an empty vector.
This is the class:
class ClipList
{
public:
ClipList();
ClipList(int);
virtual ~ClipList();
void addClip(int,int,int,int);
void getClip(int,SDL_Rect*);
int getLength();
protected:
private:
std::vector<SDL_Rect> clips;
};
ClipList::ClipList(int l)
{
clips.reserve(l);
}
void ClipList::addClip(int x,int y,int w,int h){
SDL_Rect rect;
rect.x = x;
rect.y = y;
rect.w = w;
rect.h = h;
clips.push_back(rect);
}
void ClipList::getClip(int i,SDL_Rect* rect){
rect = &(clips.at(i));
}
int ClipList::getLength(){
return clips.size();
}
And this is the function where I initialize the ClipList object. This function gets called from main.
void set_clips(Config* placlips,ClipList* clips, ClipList* flipclips){
const Setting& root = placlips->getRoot();
int x,y,w,h;
try{
Setting& clipsett = root["clips"];
int cliplen = clipsett.getLength();
clips = new ClipList(cliplen);
flipclips = new ClipList(cliplen);
for(int i=0;i<cliplen;i++){
const Setting& c = clipsett[i];
if(!(c.lookupValue("x",x)&&c.lookupValue("y",y)&&c.lookupValue("w",w)&&c.lookupValue("h",h))){
continue;
}
clips->addClip(x,y,w,h);
}
}catch(const SettingNotFoundException &nfex){
cerr << "Setting not found at" << nfex.getPath() << endl;
}
}
Regardless of whether the ClipList objects get initialized in main or set_clips, clips.push_back(rect) doesn't work. The capacity of the vector changes but no object gets stored so I end up with a segfault if I try to do anything else with the vector, even checking if the vector is empty or not.
I am going to guess, the signature of the function
void set_clips(Config* placlips,ClipList* clips, ClipList* flipclips);
is the culprit. You are allocating memory for clips and flipclips in this function but since the pointers are passed by value, the calling function does not see the allocated memory.
If you change the function signature to:
void set_clips(Config* placlips, ClipList*& clips, ClipList*& flipclips);
your problems should go away.
clips.push_back(rect) is working fine. Your set_clips function allocates new ClipList instances but does not pass those pointers back to the caller. The caller is probably attempting to use a garbage pointer as an initialise instance and that is why you are getting a segfault.
You need to pass the created objects back. You should use something like std::shared_ptr<> to do that instead of bare pointers.
Update on how to do this without using std::shared_ptr<>:
You need to keep track of ownership and deal with exceptions. In terms of the actual passing, the rule I use (originally from Lakos in "Large Scale C++ Software Design") is that parameters that are return values (as you are attempting to use them) are pointers, and read-only parameters are by value or const-reference. Return values come first.
So, your set_clips function should look like this:
void set_clips(ClipList** clips, ClipList** flip_clips, Config const& placlips)
When you call set_clips you pass a pointer to each pointer that will receive the allocated value, and pass a const-reference to the placlips object that is not modified by the function.
You would all it something like this:
ClipList* clips = 0;
ClipList* flip_clips = 0;
set_clips(&clips, &flip_flips, placlips);
// ... then do whatever comes next.
But combining those rules with std::shared_ptr<> or boost::shared_ptr<> is better and the "modern C++" style.