Declare pointer as class member C++ - c++

I'm trying to write a C++ class with a couple of pointers to ints as private members.
I get this exception when trying to assign a value to the pointer address:
Unhandled exception at 0x000B140A in test.exe: 0xC0000005: Access violation writing location 0x00000000.
Here is the minimum amount of code that will reproduce the problem on my machine
#include "stdafx.h"
class Chunker {
public:
Chunker(int cx, int cy);
private:
int chunkSizeX, chunkSizeY;
int *yOff, *xOff;
};
Chunker::Chunker(int cx, int cy){
chunkSizeX = cx;
chunkSizeY = cy;
*xOff = 0;
*yOff = 0;
};
int main(int argc, char *argv)
{
Chunker chunker(12, 12);
return 0;
}
I just can't figure out what is wrong here?

You need to declare memory somewhere for your pointers
Chunker::Chunker(int cx, int cy)
: chunkSizeX{cx},
chunkSizeY{cy}
{
xOff = new int(0);
yOff = new int(0);
}
Otherwise you are assigning a value to a pointer that does not yet have an address.
Obviously if your class is the one that allocates the memory, you need to clean it up too
Chunker::~Chunker()
{
delete xOff;
delete yOff;
}
If your class is the one allocating memory, you also might want to consider having the members be
std::unique_ptr<int> xOff;
std::unique_ptr<int> yOff;

Alternative to #Cuber's reply is to replace *xOff = 0; by xOff = nullptr; (without the *). But why pointers?
Chunker::Chunker(int cx, int cy)
: chunkSizeX{cx},
chunkSizeY{cy}
{
xOff = nullptr;
yOff = nullptr;
}
...
Chunker::~Chunker()
{
delete xOff;
delete yOff;
}

Related

Unhandled exception at 0x000FBA44 in Top Down Shooter

I recently posted a question dealing with linker errors... Well for whatever reason those errors went away and is replaced with this. When I try to run my program, the window opens and it appears to run, however Visual Studio 2013 then presents me with the error:
Unhandled exception at 0x000FBA44 in Top Down Shooter.exe: 0xC0000005: Access violation reading location 0xCCCCCCD0.
And then takes me to a xutility file with a breakpoint here:
#if _ITERATOR_DEBUG_LEVEL == 2
if (_Myproxy != _Parent_proxy)
{ // change parentage
_Lockit _Lock(_LOCK_DEBUG);
_Orphan_me();
_Mynextiter = _Parent_proxy->_Myfirstiter;
_Parent_proxy->_Myfirstiter = this;
_Myproxy = _Parent_proxy;
}
The arrow is on the _Mynextiter line. Does anyone know what is happening? I was initially using iterators to help go through some lists that I had, but I commented them out yet I still get this error and I'm not sure why
Edit:
Ok, So after going back through the stack of methods called, the last piece of code that was called that was mine was this:
ChunkManager::ChunkManager(b2World *w){
AbstractChunk *chunk = generateChunk(0, 0);
loadedChunks.push_back(*chunk);
for (int i = 0; i < 64; i++){
for (int p = 0; p < 64; p++){
if (std::rand() > .7){
AbstractBlock block(i, p, 0, w);
}
}
}
}
Now I remember when I wrote this I thought it was strange because loadedChunks is an std::list... I have never used lists so I thought it was strange that the list would only accept a pointer to a pointer to an object where in the <> of the list it clearly takes an object... I think this might be the source of my problem but I don't know how to fix it
Second Edit: Here is the ChunkManager class so you can see the lists I have
#pragma once
#include <iostream>
#include<list>
#include<vector>
#include "AbstractChunk.h"
#ifndef CHUNKMANAGER_H
#define CHUNKMANAGER_H
class ChunkManager
{
public:
ChunkManager();
ChunkManager(b2World *world);
~ChunkManager();
bool isChunkLoaded(int x, int y);
bool isChunkGenerated(int x, int y);
void loadChunksArround(int x, int y);
AbstractChunk* loadChunk(int x, int y);
int unloadChunk(int x, int y);
std::list<AbstractBlock>* getLoadedBlocks();
private:
b2World *world;
std::list<AbstractChunk> loadedChunks;
std::list<AbstractBlock> loadedBlocks;
AbstractChunk* generateChunk(int x, int y);
};
#endif
AbstractChunk.cpp:
#include "AbstractChunk.h"
AbstractChunk::AbstractChunk()
{
}
AbstractChunk::AbstractChunk(int x, int y){
xpos = x;
ypos = y;
}
int AbstractChunk::getXpos(){
return xpos;
}
AbstractChunk::~AbstractChunk()
{
}
AbstractBlock.cpp:
#include "AbstractBlock.h"
AbstractBlock::AbstractBlock()
{
}
AbstractBlock::AbstractBlock(int x, int y, float roation, b2World *world){
}
sf::Sprite AbstractBlock::draw(){
sf::Sprite sprite;
return sprite;
}
void AbstractBlock::destroy(b2World *world){
}
AbstractBlock::~AbstractBlock()
{
}
ChunkManager.cpp:
#include "ChunkManager.h"
ChunkManager::ChunkManager(){
}
//Ignore this, working on it now
void ChunkManager::destroy(){
for (int i = 0; i < loadedChunks.size; i++){
loadedChunks.
}
}
ChunkManager::ChunkManager(b2World *w){
AbstractChunk* chunk = generateChunk(0, 0);
loadedChunks.push_back(chunk);
for (int i = 0; i < 64; i++){
for (int p = 0; p < 64; p++){
if (std::rand() > .7){
AbstractBlock block(i, p, 0, w);
}
}
}
}
std::list<AbstractBlock>* ChunkManager::getLoadedBlocks(){
return &loadedBlocks;
}
ChunkManager::~ChunkManager()
{
}
AbstractChunk* ChunkManager::generateChunk(int x, int y){
if (!isChunkGenerated(x,y)){
AbstractChunk chunk(x, y);
return &chunk;
}
else
return nullptr;
}
bool ChunkManager::isChunkGenerated(int x, int y){
return false;
}
AbstractChunk* ChunkManager::loadChunk(int x, int y){
return nullptr;
}
void ChunkManager::loadChunksArround(int x, int y){
int chunkX = std::floor(x / 16);
int chunkY = std::floor(y / 16);
for (int i = -1; i < 2; i++){
for (int p = -1; p < 2; p++){
loadChunk(i, p);
}
}
}
Your code denotes some confusion on very fundamental concepts like value and identity in C++. For example in
AbstractChunk *chunk = generateChunk(0, 0);
seems that generateChunk will allocate an object on the free store.
Then however in:
loadedChunks.push_back(*chunk);
you are storing a copy of the allocated object in a container and the pointer is never used later (thus leaking the object).
Wildly guessing from the name, AbstractChunk is an abstract class with derived classes and the list should be an heterogeneous list of chunks of different types.
This is simply not possible in C++ (see the fundamental concepts of "slicing" and "copy semantic" of C++). You need to use a list of pointers to chunks instead.
Note that piling up a long stream of statements without understanding deeply how things works is a suicide strategy with C++. Even the fact that you assume that if you make a mistake the system will tell you so denotes you don't know how C++ works (see "undefined behavior" concept).
C++ cannot be learned by experimentation. You need to read a good book or two from cover to cover first.
There is no way to learn C++ except than by reading (and the smarter you are the worse the guessing approach will work... the reason is that in quite a few places the correct answer is not logical, but a consequence of an historic accident).

image pointer to pointer initialization in C++

I meet a problem when dealing with image initialization.
I have a class like this:
Class MyImage
{
private:
unsigned int** image;
const unsigned int w;
const unsigned int h;
public:
MyImage(unsigned int** _image,unsigned int _w,
unsigned int _h); // copy constructor
}
it seems if I use copy constructor as above, I need to delete image first like below:
MyImage(unsigned int** _image,unsigned int _w,unsigned int _h)
{
if (image)
{
for (int i = 0;i < w;++i)
delete[] image[i];
delete[] image;
}
// .. copy _image to imge
}
however if w and h are const members, it seems w and h must be initialized in the inialization list, like below:
MyImage(unsigned int** _image,unsigned int _w,unsigned int _h): w(_w),h(_h)
{
// ..code
}
then I can't delete image because w changes before it. My Question is what should I do if I don't want to eliminate const decoration in w and h? Any method? Thanks.
This is not a copy-constructor
MyImage(unsigned int** _image,unsigned int _w,unsigned int _h)
This is a copy-constructor
MyImage(const MyImage &image)
Don't use : w(_w) and first delete previous image, then use w = image._w.
However, you don't need delete anything because it's a constructor.
Use an encapsulated std::vector to manager the image data. The default copy constructor, move constructor, assignment operator, move assignment operator and default destructor will all be automatically generated for you and do the right things. Further by allocating the image data in a continuous block of memory and using a stride over row (or column) major order, it will be far more efficient than allocating a new memory block for every line...
struct MyImage
{
const size_t w, h;
vector<int> image;
MyImage(const vector<int>& image, size_t w, size_t h)
: image(image)
, w(w)
, h(h)
{
assert(image.size() == w*h);
}
MyImage(vector<int>&& image, size_t w, size_t h)
: image(move(image))
, w(w)
, h(h)
{
assert(image.size() == w*h);
}
int& pixel(size_t x, size_t y) { return image[w*y+x]; }
int pixel(size_t x, size_t y) const { return image[w*y+x]; }
};
In your case, there is nothing wrong with w and h being a const. You can write your constructor in the following way:
MyImage(unsigned int** _image,unsigned int _w,unsigned int _h)
: w(_w), h(_h)
{
// No data is allocated in the memory pointed to by image yet
// We have to allocate it here. Remember, that copy-ctor is
// a constructor, so it operates on newly created instance,
// not on an existing one.
image = new unsigned int * [h];
for (int i = 0; i < h; i++)
{
image[i] = new unsigned int [w];
memcpy(image[i], _image[h], w * sizeof(unsigned int));
}
}
From my image-processing experience, consider storing an image as a single table, row-by-row. You can access (x, y)-th element by calling data[y * w + x]; In such case, you can simplify your copy ctor:
MyImage::MyImage(unsigned int * source, int newW, int newH)
: w(newW), h(newH)
{
image = new unsigned int[w * h];
memcpy((void *)image, (void *)source, w * h * sizeof(unsigned int));
}
The copy constructor, as C++ community understands this term, would look like this:
MyImage::MyImage(const MyImage &source)
: w(source.w), h(source.h)
{
image = new unsigned int[w * h];
memcpy((void *)image, (void *)source.image, w * h * sizeof(unsigned int));
}
Notice, that the image field does not exist when you call the constructor, so you do not need to free anything.
// Your code
MyImage(unsigned int** _image,unsigned int _w,unsigned int _h)
{
// Class is allocated into some part of memory, which might
// have been used, so in effect this may be actually true,
// because image may contain some rubbish data
if (image)
{
// But this will result mostly likely in Access Violation
// error, because you would try to use (free!) some random
// data in memory.
for (int i = 0;i < w;++i)
delete[] image[i];
delete[] image;
}
// .. copy _image to imge
}
If you need an assign-like method, which copies contents of some image (either stored in a unsigned int * or in another Image class) to an existing instance of Image, w and h cannot be const.

Access violation when using int (*)[4] in structure

I define arrays of integers in my code:
unsigned int tara[1024][3];
unsigned int data[1024][4];
I have storage structure, that allows me to pass them as void*:
struct storage {
unsigned int (*data)[4];
unsigned int (*tara)[3];
};
This is my use of structure above:
int main() {
unsigned int tara[1024][3];
unsigned int data[1024][4];
storage but_data;
but_data.data = data;
but_data.tara = tara;
tara_button.setCallback(taraButtonCallback, (void*)&but_data); //Some UI class
while(true); //The program
return 0;
}
In callback, this is how I try to access data:
bool taraButtonCallback(Opencv_Button* but, void* but_data)
{
storage* data_struct = (storage*)but_data;
int max = -5;
int max_value = 0;
cout<<data_struct->data[0][0]<<'\n'; //!!ERROR!!
return true;
}
This is runtime error I get:
Unhandled exception at 0x00394f1c in OpenCV.exe: 0xC0000005: Access violation reading location 0x00000005.
Edit:
The problem is not related to to where is the but_data defined! This callback works:
bool taraButtonCallback(Opencv_Button* but, void* but_data)
{
storage* data = (storage*)but_data;
set_tara(data->data, data->tara, *data->mat);
*(data->tara_set) = true;
return true;
}
void set_tara(unsigned int data[][4], unsigned int tara[][3], Mat &UI_bot)
{
UI_bot = Scalar(0, 0, 0);
for(int x=0; x<cam_frame_width; x++) {
tara[x][0]=data[x][0];
tara[x][1]=data[x][1];
tara[x][2]=data[x][2];
}
}
At the time the callback is called, but_data is already destroyed:
storage but_data;
It is allocated locally, which means that its lifetime is limited with the end of current function. After the function is completed, it ceases to exist, and the callback uses a dangling pointer.
Just assign it to a variable and print it
int taraButtonCallback(void* but_data)
{
struct storage* data = ( struct storage*)but_data;
int max = -5;
int max_value = 0;
int val = data->data[0][0];
cout <<val ; //!!works!!
return 0;
}
I think cout is unable to handle [][] in this case .. I am not sure why someone can enlighten both of us
You could try allocating the variable storage but_data like this:
storage *but_data = new storage;
effectively creating a variable with infinite lifetime.
Than you would define your callback function a bit differently (because you already have a pointer, so you do not need the address of the variable) - like this:
tara_button.setCallback(taraButtonCallback, (void*)but_data);
//note the lack of '&' sign before the but_data variable name
Just don't forget to delete it after you no longer need it!
delete but_data;

Segmentation Fault - altering struct (within another struct's) variables

I have this, in my header:
struct Surface {
char *objectName;
int xPos;
int yPos;
SDL_Surface *surface;
};
struct WorldSurface {
Surface *surface = new Surface[MAX_SURFACES];
int counter = 0;
int current = 0;
};
WorldSurface *worldSurface;
I then initialize the worldSurface in the .cpp:
WorldSurface *worldSurface = new WorldSurface[MAX_LEVELS];
And this function, I can't get to work no matter what, have tried messing around with = NULL, pointers, the -> instead of .'s... (do have in mind I'm not very savvy of pointer subjects)
void drawClass::addSurface(char* objectName, char* surfaceFile, int xPos, int yPos, int drawLevel) {
int cnt = worldSurface[drawLevel].counter;
worldSurface[drawLevel].surface[cnt].objectName = objectName;
worldSurface[drawLevel].surface[cnt].surface = load_image(surfaceFile);
worldSurface[drawLevel].surface[cnt].xPos = xPos;
worldSurface[drawLevel].surface[cnt].yPos = yPos;
worldSurface[drawLevel].counter++;
}
It's 10 worldSurfaces, each containing 50 surface structs, and I want to acess the struct, which is inside the worldSurface[drawLevel], and the surface struct I want to access is known in the worldSurface, in the .counter variable. But all of the acesses to the underlying surface struct fail with segmentation fault, and I have no clue why...
Thanks for the help!
Your WorldSurface isn't defined nor initialized properly:
struct WorldSurface {
Surface *surface = new Surface[MAX_SURFACES];
int counter = 0;
int current = 0;
};
You can't initialize your data in place along with the declaration of the class. You need to do this in a constructor, e.g.:
struct WorldSurface {
Surface *surface;
int counter;
int current;
};
...
WorldSurface::WorldSurface():
counter(0),current(0),surface(new Surface[MAX_SURFACES]){}

Dynamically allocating array of objects

I need a double pointer of type DizzyCreature (my class) to point to an array of DizzyCreature pointers. When I run it I get "Access violation reading location 0x...". I can make a DizzyCreature* and call its member functions just fine, but when cannot run through the array and do the same thing for each obj.
I am following these instructions:
http://www.cplusplus.com/forum/beginner/10377/
Code
Server.h:
class Server
{
public:
Server(int x, int y, int count);
~Server(void);
void tick();
private:
DizzyCreature** dcArrPtr;
DizzyCreature* dcPtr;
int _count;
};
Server.cpp:
Server::Server(int x, int y, int count)
{
dcPtr = new DizzyCreature[count]; // this works just fine
dcArrPtr = new DizzyCreature*[count]; // this doesn't (but gets past this line)
_count = count;
}
Server::~Server(void)
{
delete[] *dcArrPtr;
delete[] dcPtr;
}
void Server::tick()
{
dcPtr->takeTurn(); // just fine
for (int i = 0; i < _count; i++) {
dcArrPtr[i]->takeTurn(); // crash and burn
}
}
EDIT:
The member function takeTurn() is in a parent class of DizzyCreature. The program makes it into the function, but as soon as it attempts to change a private member variable the exception is thrown. If it matters, DizzyCreature is of type GameCreature and WhirlyB as this is an assignment on MI.
You have allocated space for dcArrPtr, but didn't allocate every object in this array. You must do following:
Server::Server(int x, int y, int count)
{
dcPtr = new DizzyCreature[count];
dcArrPtr = new DizzyCreature*[count];
for ( int i = 0; i < count; i++ ) {
dcArrPtr[ i ] = new DizzyCreature;
}
_count = count;
}
Server::~Server(void)
{
for ( int i = 0; i < count; i++ ) {
delete dcArrPtr[ i ];
}
delete[] *dcArrPtr;
delete[] dcPtr;
}
This:
dcPtr = new DizzyCreature[count];
"creates" an array of DizzyCreatures, whereas:
dcArrPtr = new DizzyCreature*[count];
"creates" an array of pointers to DizzyCreatures, but crucially doesn't create instances for those pointers to point to.
The preferred solution is to use a standard container for tasks like this anyway though. If you really want to do it like this (and are aware that it's not best practice to do this manually) then you'll need a loop to call new for eachelement in the array of pointers.
You allocate an array of count pointers instead of an array of count objects.
Instead of
dcArrPtr = new DizzyCreature*[count];
you might want to
dcArrPtr = new DizzyCreature[count];
You're allocating an array of pointers, but those pointers aren't valid until you set them to something.
double **arr = new double*[10];
for(int i=0;i<10;++i) {
arr[i] = new double[10];
}
That said, when starting out with C++ you should probably avoid raw arrays and instead use std::array and std::vector:
class Server
{
public:
Server(int x, int y, int count);
void tick();
private:
std::vector<std::vector<DizzyCreature>> dcArrPtr;
std::vector<DizzyCreature> dcPtr;
};
Server::Server(int x, int y, int count)
{
dcPtr.resize(count);
dcArrPtr.resize(count);
}
void Server::tick()
{
dcPtr[0].takeTurn();
for (int i = 0; i < dcArrPtr.size(); i++) {
dcArrPtr[i][0].takeTurn();
}
}
Use a
std::vector<std::vector<DizzyCreature>>
Furthermore, if you want to use raw pointers (which I do not recommend), you'll have to allocate memory for each pointer in your array.
class A
{
std::vector<std::vector<int>> v_;
public:
A()
: v_(500, std::vector<int>(500))
{} // 500 x 500
};
class B
{
int** v_;
public:
B()
: v_(new int*[500])
{ // not even exception safe
for (int i = 500; i--; )
v_[i] = new int[500];
}
~B()
{
for (int i = 500; i--; )
delete[] v_[i];
delete[] v_;
}
};
If you would have seen the implementation of dynamic memory allocation of 2-Dimensional array . That would have given you a better insight of how to proceed in such cases . Most of the answers has already answered you what to do . But just go through any link and see how is memory allocated in case of 2-D array . That Will also help you .