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.
Related
I'm working on one of assignments to do with image manipulation (blending and zooming) and I've ran into a problem that I have hard time overcoming.
Structure of my application
Class Image
rgb struct: contains floats (they're flattened pixels) and overloaded operators.
pixels: a 1d array of pixels which is initialized via constructor to be h * w
Class destructor.
Destructor looks a little like this...
virtual ~Image()
{
if (pixels != NULL)
delete[] pixels;
}
Now I'm using another class called Filter which inherits from Image
class Filter: public class Image
std::vector of Image imgStack; Container for images that I'm going to blend
std::vector of Rgb pixelBuffer; A container for the pixels for each images one pixel. This is not dynamic so I'm not worried about deleting this.
Destructor for the derived class.
~Blend()
{
delete &imageStack;
}
what this part of my main.cpp looks like...
while (userInput != 5)
{
switch(userInput)
case 1:
{
Blend *meanImage = new Blend(3263, 2505, 13);
meanImage->writePPM("Mean_" + std::to_string(count) + ".ppm");//every iteration, the file name is unique
meanImage->~Blend();
}
}
In my main.cpp I'm basically running 13 images into the Blend object which stores the images in the vector container to do all my functionality on. During the run time the space used is around 1.3GB, but since my object is in a loop (i have a menu for multiple functionality) the object doesn't usually leave the scope so the destructor isn't automatically called, so I call it manually like this; medianImage->~Blend(); Now the all the error says is that my application "has triggered a breakpoint" and that's it... Note, no breakpoint is found anywhere. I'm aware that it's generally bad to use dynamic arrays because it causes all sorts of memory problems (if it's done by me), but I want to fix this just so I know how to solve these in the future.
If you have any questions of the code, I can post snippers.
Edit: here's an my Blend class.
#pragma once
#include "stdafx.h"
#include "Image.h"
#include <vector>
#include <string>
class Blend : public Image
{
private:
std::vector<Image> imageStack;
std::vector<Rgb*> pixelBuffer;//only works with pointers (no copying)
int m_noOfImages;
Rgb* getMedianFromSet();
Rgb getMeanFromSet();
Rgb getStdDev(Rgb meanPix);
public:
Blend(int width = 0, int height = 0, int noOfImages = 0):Image(width, height), m_noOfImages(noOfImages), imageStack(noOfImages), pixelBuffer(noOfImages)
{}
public:
void stack(bool push = true);
void meanBlend();
void medianBlend();
void sigmaClipping(float sigma = 0.5f);
~Blend()
{
delete &imageStack;
}
};
#pragma once
#include "stdafx.h"
#include "Image.h"
#include <vector>
#include <string>
#include <memory>
class Blend : public Image
{
private:
std::vector<Image> imageStack;
// Changed to shared_ptr<T> could use unique_ptr<T> depending on need.
std::vector<std::shared_ptr<Rgb>> pixelBuffer;//only works with pointers (no copying)
int m_noOfImages;
Rgb* getMedianFromSet();
Rgb getMeanFromSet();
Rgb getStdDev(Rgb meanPix);
public:
Blend(int width = 0, int height = 0, int noOfImages = 0):Image(width, height), m_noOfImages(noOfImages), imageStack(noOfImages), pixelBuffer(noOfImages)
{}
public:
void stack(bool push = true);
void meanBlend();
void medianBlend();
void sigmaClipping(float sigma = 0.5f);
// Clear Entire Buffer
void cleanup() {
// When using the heap with smart pointers
for ( auto item : containerVariable ) {
item.reset();
item = nullptr;
}
containerVariable.clear();
}
// Remove Single Element
void remove( unsigned idx ) {
// Write function to remove a single element from vector
}
~Blend()
{
// This is definitely wrong here: You are trying to delete a reference
// to a template container that is storing `Image` objects that
// are on the stack.
// delete &imageStack;
}
};
It is better to write a function to clean up memory, and to remove specific elements from containers when using dynamic memory than it is to use a class's destructor.
I have a class which is basically a wrapper for a 2D matrix of pointers to another object, and the matrix is made of vectors.
For some reason, the program crashes whenever the destructor of my class is being called, and it seems like it's trying to delete the pointers even if they are nullptr, which causes a crash.
Here are my .h and .cpp file:
cpp file:
RotationSolution.h:
#ifndef PUZZLESOLVER_ROTATIONSOLUTION_H
#define PUZZLESOLVER_ROTATIONSOLUTION_H
#include <vector>
#include <fstream>
#include "PuzzlePiece.h"
using namespace std;
class RotationSolution {
private:
int _height, _width;
vector<vector<PuzzlePiece*>> _matrix;
public:
RotationSolution();
RotationSolution(int height, int width);
vector<PuzzlePiece*>& operator[](int row);
int get_height() const;
int get_width() const;
};
#endif //PUZZLESOLVER_ROTATIONSOLUTION_H
RotationSolution.cpp:
#include "RotationSolution.h"
vector<PuzzlePiece*>& RotationSolution::operator[](int row) {
return _matrix[row];
}
RotationSolution::RotationSolution() : RotationSolution(0, 0) {}
RotationSolution::RotationSolution(int height, int width) :
_height(height), _width(width), _matrix(vector<vector<PuzzlePiece*>>(_height, vector<PuzzlePiece*>(_width, nullptr)))
{}
int RotationSolution::get_height() const {
return _height;
}
int RotationSolution::get_width() const {
return _width;
}
The code is actually crashing in a section that looks like this:
for (auto length: _rowLengths) {
auto height = size / length;
_sol = RotationSolution(height, length);
...
}
in the second iteration in the _sol = RotationSolution(height, length); line.
When debugging, the code the sends the crash signal is from new_allocator.h (which I'm pretty sure is a lib file):
// __p is not permitted to be a null pointer.
void
deallocate(pointer __p, size_type)
{ ::operator delete(__p); }
I am still new to c++ so please forgive any noob mistakes and bad practices :)
there is a design flaw in RotationSolution class - it contains member variable _matrix which stores raw pointers and it misses properly defined assigment operator which will clone objects stored inside _matrix. Default generated copy assigment operator will just copy pointers which may lead to double freeing memory and crash (here is some explanations what is happening and why). Try to use "vector< vector< std::shared_ptr< PuzzlePiece > > > _matrix" (also do #include "memory") it should fix most of problems with wrong memory management. Here is tutorial to read about smart pointers.
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_() {}
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.
Hi i am trying to understand how to use the 'this' pointer. Now i wrote a sample program which uses a class Image which is a subclass of a class BMP. Now the functions TellWidth and TellHeight are declared in the BMP class. Now the compiler gives me an error which says that the TellWidth function does not exist in Image. But as Image is a subclass of BMP shouldnt it inherit the functions in BMP.
How do i resolve this
void Image :: invertcolors()
{
int x;
int y;
int width =(*this).TellWidth();
int height = (*this)->TellHeight();
for(x=0,x<=height-1;x++){
for(y=0,y<=width-1;y++){
(*this)(x,y)->Red = (255 - (*this)(x,y)->Red);
(*this)(x,y)->Blue = (255 - (*this)(x,y)->Blue);
(*this)(x,y)->Green = (255 - (*this)(x,y)->Green);
}
}
delete width;
delete height;
}
Image
class Image : public BMP
{
public:
void invertcolors();
void flipleft();
void adjustbrightness(int r, int g, int b) ;
};
This class is too big to post here, here is a relavent excerpt
class BMP {
private:
int Width;
int Height;
public:
int TellBitDepth(void) const;
int TellWidth(void) const;
int TellHeight(void) const;
};
TellWidth() is most likely declared as private (or has no accessor modifier) in the BMP class. It needs to be protected or public for the Image class to be able to access it, and it needs to be also virtual, if you want to be able to override it in the Image class.
And the proper this usage is like this:
int width = this->TellWidth();
int height = this->TellHeight();
Read this for a quick tutorial on this.
One point about this: you rarely need to mention it explicitly. The usual exception is when you need to pass it into a non-member function (which doesn't seem to be the case here.)
When you're inside of a class member function, this->field can be accessed simply as field, and this->function(x) can be invoked as function(x).
Here are some comments on your code. I hope they're helpful.
void Image :: invertcolors()
{
// Don't define these here; that's old C-style code. Declare them where
// they're needed (in the loop: for (int x=0...)
int x;
int y;
// Change the lines below to
// int width = TellWidth();
// int height = TellHeight();
// (*this).TellWidth() should work, but is redundant;
// (*this)->TellHeight() should probably *not* work, as once you've
// dereferenced *this, you're dealing with an object instance, not a
// pointer. (There are ways to make (*this)->that() do something useful,
// but you're probably not trying something like that.)
int width =(*this).TellWidth();
int height = (*this)->TellHeight();
for(x=0,x<=height-1;x++){
for(y=0,y<=width-1;y++){
// After locating the BMP class through google (see Edit 2),
// I've confirmed that (*this)(x,y) is invoking a (int,int) operator
// on the BMP class. It wasn't obvious that this operator
// was defined; it would have been helpful if you'd posted
// that part of the header file.
(*this)(x,y)->Red = (255 - (*this)(x,y)->Red);
(*this)(x,y)->Blue = (255 - (*this)(x,y)->Blue);
(*this)(x,y)->Green = (255 - (*this)(x,y)->Green);
}
}
// These are int values. They can't be deleted, nor do they need to be.
// I'm sure the compiler has told you the same thing, though perhaps not
// in the same way.
delete width;
delete height;
}
EDIT: Looks like there's someone else taking the same course as the OP. The example presented there makes it clearer that Image is supposed to have some sort of array accessor, which may explain what (*this)(x,y)->Red = (255 - (*this)(x,y)->Red) was intended to achieve.
EDIT 2: Here's the source for the original BMP class.
class Image is defined as
class Image : public BMP
{
public:
void invertcolors();
void flipleft();
void adjustbrightness(int r, int g, int b) ;
};