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

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;

Related

c++ int member changes on its own

I am new to c++.
It looks like member variable _scheduleSize gets value kind of "integer_half_max" without any reason. Could someone please explain me why is this happening?
Invocation
leds.addSchedulePoint(new ScheduledLedPoint(ScheduleTime(9), 0));
of method:
void ScheduledLeds::addSchedulePoint(ScheduledLedPoint *schedulePoint) {
Serial.print("_scheduleSize:");
Serial.println(_scheduleSize);
_schedule[_scheduleSize++] = schedulePoint;
Serial.print("_scheduleSize:");
Serial.println(_scheduleSize);
for (size_t i = 0; i < _scheduleSize; i++) {
Serial.println(_schedule[i]->getLevel());
}
}
results in such console output :
_scheduleSize:0
_scheduleSize:1073680860
0
Exception (28):
epc1=0x40206514 epc2=0x00000000 epc3=0x00000000 excvaddr=0x00000010 depc=0x00000000
Below you can see entire class:
class ScheduledLeds {
public:
ScheduledLeds(int pin);
void addSchedulePoint(ScheduledLedPoint *schedulePoint);
void process(ScheduleTime currentTime);
void freezeLedLevel(int targetLevel, int minutes);
int _pin;
private:
ScheduledLedPoint *_schedule[];
int _scheduleSize;
int _count;
int _size;
long _unfreezeTime;
int _lastLevel;
ScheduleTime _lastTime;
void setTransitionalLightLevel(ScheduleTime now, ScheduledLedPoint nextPoint);
void setLightLevel(int targetLevel);
};
ScheduledLeds::ScheduledLeds(int pin) {
pinMode(pin, OUTPUT);
_pin = pin;
_scheduleSize = 0;
_size = 10;
_unfreezeTime = millis();
ScheduledLedPoint *_schedule[_size];
}
void ScheduledLeds::addSchedulePoint(ScheduledLedPoint *schedulePoint) {
Serial.print("_scheduleSize:");
Serial.println(_scheduleSize);
_schedule[_scheduleSize++] = schedulePoint;
Serial.print("_scheduleSize:");
Serial.println(_scheduleSize);
for (size_t i = 0; i < _scheduleSize; i++) {
Serial.println(_schedule[i]->getLevel());
}
}
ScheduledLedPoint *_schedule[]; is not valid C++ and shouldn't compile. Some compilers accept it as an extension - but even there, it's an array of zero size; _schedule[x] exhibits undefined behavior for any value of x.
When you write ScheduledLedPoint *_schedule[_size] in the constructor, that doesn't affect the data member named _schedule, as you seem to believe. Instead, it creates and immediately destroys a local variable that also happens to be named _schedule; this has exactly zero net effect.
For an array-like data structure of variable size, use std::vector.
because you have syntax error including this recursive function

How can I allocate memory and return with in c++ with function?

I create a table in c++. I have a class with the table skills. I would like to get memory for the square table with function, but I don't know how I should code the constructor and the function for memory allocation.
I get the size from keyboard and I'd like to give this return statement for an other function that allocates the memory. Table must be an 2-dimensions array[][] or matrix.
#include <iostream>
using namespace std;
class Table {
unsigned int size;
public:
unsigned int GetTableSize();
unsigned int *GetMemory(unsigned int);
};
unsigned int Table::GetTableSize() {
cout << "Give size: " << endl;
cin >> size;
return size;
}
unsigned int *Table::GetMemory(unsigned int s){
s = size;
return new unsigned int[s * s];
}
int main()
{
Table tab;
tab.GetTableSize();
tab.GetMemory();
return 0;
}
*GetMemory function must return with the memory size of the table. I have problem with tab.GetMemory. I tried tab.*GetMemory as well.
tab*GetMemory: QT creator says: GetMemory is not declared.
tab.GetMemory: Qt creator says: not matching function for call 'Table::Getmemory'.
First of all your Question is not that clear, I would like to inform regarding the error you are getting in Qt.
In Your Code, You are not passing any value in the below line
"tab.GetMemory();"
How ever your function expects an unsigned integer value.
I would like to suggest you that you can modify the below code snippet as follows
Your Code:
unsigned int *Table::GetMemory(unsigned int s){
s = size;
return new unsigned int[s * s];
}
Modified Code:
unsigned int *Table::GetMemory(){
//s = size;
return new unsigned int[size * size];
}
Hope that Helps.

Initializing chained hash table to NULL. Get "lvalue required as left operand of assignment" error. Why? Here is my code:

I am trying to create a chained hash table. I have started by building a dynamic array and am now trying to initialize each array pointer to NULL. But I get the error "lvalue required as left operand of assignment". Why? Here is my code:
#include <iostream> // for i/o functions
using namespace std;
const int HTSIZE = 997; //size of the hash table
struct CHTNode
{
int value;
CHTNode *next;
};
void InitializeTable(CHTNode* &cHT);
int main()
{
CHTNode *chainedHT;
chainedHT = new(nothrow) CHTNode[HTSIZE];
if (chainedHT == NULL)
{
cout << "ERROR: Memory allocation error"
<< endl;
return 1;
} //end if
else
{
InitializeTable(chainedHT);
}
}
void InitializeTable(CHTNode* &cHT)
{
for (int i = 0; i < HTSIZE; i++)
&cHT[i] = NULL; //ERROR FOR THIS LINE
}
The address-of operator & returns the address of the given expression, so &cHT[i] evaluates to the address of the ith element of cHT. It seems you're trying to assign to the variable cHT[i], but what you're doing right now is trying to assign to the address value of cHT[i], which makes no more sense than trying to assign to a constant.
You do not have an array of pointers. You allocated an array of objects of type CHTNode.
You could value initialize this array when it was allocated. For example
chainedHT = new(nothrow) CHTNode[HTSIZE] {};
If you want to write a separate function that zero-injitialize each element of the array then the function could be declared like
void InitializeTable( CHTNode* cHT, int n );
and defined like
void InitializeTable( CHTNode* cHT, int n )
{
for ( int i = 0; i < n; i++ ) cHT[i] = {};
}
As for erroneous statement
&cHT[i] = NULL;
then it does not make a sense. Expression &cHT[i] is a temporary object that you are try to assign.

c++ memory leak caused by vector of structs

The memory leak caused by the line indicated. "pendingSendReqs.push_back(&f);" in the sendreq() method. I am new to c++ so I can't seem to figure out why the memory leak is occuring. The size of memory leaked is 16 bytes.
class Station {
struct Frame {
enum { Token, Data, Ack } type; // type of frame
unsigned int src; // source id
unsigned int dst; // destination id
unsigned int prio; // priority
} frame;
unsigned int stnId;
static unsigned int requests; // total send requests (if needed)
void data( Frame frame ); // pass frame
void main(); // coroutine main
Station *nextStation;
vector<Frame*> pendingSendReqs;
public:
Station( unsigned int id ) : stnId(id) { }
~Station() {
for (int i = 0; i < pendingSendReqs.size(); i++) {
delete pendingSendReqs.at(i);
cout << "~: " << pendingSendReqs.at(i) << endl;
}
}
//unsigned int getId() { return stnId; }
void setup( Station *nexthop ) { // supply next hop
//*nexthop is the object
nextStation = nexthop;
//cout << "size: " << sizeof(*nexthop) << endl;
}
void sendreq( unsigned int round, unsigned int dst, unsigned int prio ) { // store send request
Frame f;
f.type = Frame::Data;
f.src = stnId;
f.dst = dst;
f.prio = prio;
pendingSendReqs.push_back(&f); //MEMORY LEAK CAUSED BY THIS LINE
}
void start(); // inject token and start
};
This is not a memory leak
pendingSendReqs.push_back(&f);
it is future undefined behaviour. You are storing the address of a local variable. Any attempt to de-reference one of those pointers outside of the scope of the function is undefined behaviour.
You have to ask yourself whether you really need a vector of pointers. If you don't know the answer to that, it is likely that you don't.
You're storing pointers to local variables, which will automatically get destroyed, inside the vector. This is illegal.
vector<Frame*> pendingSendReqs;
// this is a vector of pointers to struct and not a vector of structs
void sendreq( unsigned int round, unsigned int dst, unsigned int prio ) {
Frame f; // this automatic variable will get destroyed when sendreq returns
f.type = Frame::Data;
f.src = stnId;
f.dst = dst;
f.prio = prio;
pendingSendReqs.push_back(&f); //MEMORY LEAK CAUSED BY THIS LINE
// because you're going to hold on to this address which will mean
// nothing when this function returns
}
The way you intend to do it is:
vector<Frame> pendingSendReqs;
and inside sendreq:
pendingSendReqs.push_back(f); // store the object's copy instead of it's address so that it outlives the life of this local
when
void sendreq( unsigned int round, unsigned int dst, unsigned int prio )
ends,
your vector pendingSendReqs will contain pointers to variables that have been eliminated ( because are local variable ), and will contain garbage, and will give you a crash.

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 .