Error when accessing member over multiple classes - c++

I'm new to C++, and I'm writing a simple blockchain program as a sort of exercise. When I run the below code, I seem to get an error of sorts:
Process returned -1073741819 (0xC0000005)
The code is below:
#include <iostream>
#include <time.h>
#include <string>
using namespace std;
class Block
{
int data, previous_hash;
public:
string timestamp;
Block(string a, int b, int c)
{
timestamp = a;
data = b;
previous_hash = c;
};
};
string getTime()
{
time_t now = time(NULL);
struct tm tstruct;
char buf[40];
tstruct = *localtime(&now);
strftime(buf, sizeof(buf), "%X", &tstruct);
return buf; //Simple code to return current time
}
class BlockChain
{
public:
Block chain[];
BlockChain()
{
chain[0]=createGenesisBlock();
}
Block createGenesisBlock()
{
return Block(getTime(), 10, 0);
}
};
int main()
{
BlockChain myChain;
cout << "current time is " << getTime();
cout << myChain.chain[0].timestamp; //Is this correct?
}
I included a line in main() to access the string timestamp in my object mychain. I suspect this may be the problem, but i'm not sure how else I can access timestamp when its called over both Blockchain and Block classes.

Currently, BlockChain::chain is an array with unknown size. But when you access chain[0] in BlockChain's constructor, you're assuming that chain points to valid memory, which it doesn't because you never initialize it. That's why you're getting a crash due to a bad memory access. I would suggest the use of std::vector<Block> instead of Block[], which you can resize as needed:
class BlockChain {
public:
std::vector<Block> chain;
BlockChain() {
// initialize and append a new block to chain
chain.emplace_back(createGenesisBlock());
}

Related

assign array to structure pointer

Getting segmentation fault while trying to print content member using pointer l_pContent in below program.
#include <iostream>
#include <string.h>
using namespace std;
struct responseStruct {
int Handle;
int headerLen;
int bodyLen;
unsigned char* content;
};
int main()
{
unsigned char l_httpResponse[] = {1,2,3,4,5,6,7,8,9,0,1,2,'a','b','c','d','e','f','g','h','i','j','k','l','a','b','c','d','e','f','g','h','i','j','k','l',0};
struct responseStruct *l_pContent = (struct responseStruct*)l_httpResponse;
cout << l_pContent->content << endl; // Error : Segmentation Fault
return 0;
}
The variable content is a pointer to an unsigned char and so is l_httpResponse. You can therefore create an instance of the responseStruct and then assign the instance's content pointer to l_httpResponse.
Here is an example:
#include <iostream>
#include <string.h>
using namespace std;
struct responseStruct {
int Handle;
int headerLen;
int bodyLen;
unsigned char* content;
};
int main()
{
unsigned char l_httpResponse[] = {1,2,3,4,5,6,7,8,9,0,1,2,'a','b','c','d','e','f','g','h','i','j','k','l','a','b','c','d','e','f','g','h','i','j','k','l',0};
// Create instance of an responseStruct struct
responseStruct rs;
// Make content point to the start of l_httpResponse
rs.content = l_httpResponse;
// Test for access without segfault
cout << static_cast<unsigned>(rs.content[1]) << endl;
return 0;
}
Or here is a live demo.
Omitting the fact that the idea of such code is mysterious to me, here is what causes the error:
If we assume that members of the responseStruct will match ideally the data from the l_httpResponse, that sizeof(int) and sizeof(unsigned char *) are 4, that your architecture uses little-endian notation, and that your compiler uses ASCII (which it probably does), you end with:
Handle == 0x04030201
headerLen == 0x08070605
bodyLen == 0x02010009
content == 0x64636261
Now, content is a pointer, so 0x64636261 is an address in your memory. It doesn't point to your "abcde..." string. It's made up of it's first four bytes. And points at some non existing region. That's why you end up with segmentation fault.

Instance of class only allows 1 method, or program crashes

I am learning classes and OOP, so I was doing some practice programs, when I came across the weirdest bug ever while programming.
So, I have the following files, beginning by my class "pessoa", located in pessoa.h:
#pragma once
#include <string>
#include <iostream>
using namespace std;
class pessoa {
public:
//constructor (nome do aluno, data de nascimento)
pessoa(string newname="asffaf", unsigned int newdate=1996): name(newname), DataN(newdate){};
void SetName(string a); //set name
void SetBornDate(unsigned int ); //nascimento
string GetName(); //get name
unsigned int GetBornDate();
virtual void Print(){}; // print
private:
string name; //nome
unsigned int DataN; //data de nascimento
};
Whose functions are defined in pessoa.cpp
#include "pessoa.h"
string pessoa::GetName ()
{
return name;
}
void pessoa::SetName(string a)
{
name = a;
}
unsigned int pessoa::GetBornDate()
{
return DataN;
}
void pessoa::SetBornDate(unsigned int n)
{
DataN=n;
}
A function, DoArray, declared in DoArray.h, and defined in the file DoArray.cpp:
pessoa** DoArray(int n)
{
pessoa* p= new pessoa[n];
pessoa** pointer= &p;
return pointer;
}
And the main file:
#include <string>
#include <iostream>
#include "pessoa.h"
#include "DoArray.h"
#include <cstdio>
using namespace std;
int main()
{
//pessoa P[10];
//cout << P[5].GetBornDate();
pessoa** a=DoArray(5);
cerr << endl << a[0][3].GetBornDate() << endl;
cerr << endl << a[0][3].GetName() << endl;
return 0;
}
The weird find is, if I comment one of the methods above, "GetBornDate" or GetName, and run, the non-commented method will run fine and as supposed. However, if both are not commented, then the first will run and the program will crash before the 2nd method.
Sorry for the long post.
Let's look into this function:
int *get()
{
int i = 0;
return &i;
}
what is the problem with it? It is returning pointer to a local variable, which does not exist anymore when function get() terminates ie it returns dangling pointer. Now your code:
pessoa** DoArray(int n)
{
pessoa* p= new pessoa[n];
return &p;
}
do you see the problem?
To clarify even more:
typedef pessoa * pessoa_ptr;
pessoa_ptr* DoArray(int n)
{
pessoa_ptr p= whatever;
return &p;
}
you need to understand that whatever you assign to p does not change lifetime of p itself. Pointer is the same variable as others.

Pointer to Pointer to Structure (Priority Queue)

I'm a beginner (in C++, I'm coming from C (6 months experience)) and I'm trying to create a priority queue, but something is not working.
When I start the program and compile it, there are no errors. But there is nothing printed on the screen and the program crashes.
So here is the code:
PriorityQueue.h
using namespace std;
class PriorityQueue{
private:
struct pqentry_t{
string value;
float priority;
};
pqentry_t **_pqentry;
int _size;
int _next;
public:
PriorityQueue();
~PriorityQueue();
void insert(string value, float priority);
void printQueue();
};
PriorityQueue.cpp
#include <iostream>
#include <string>
#include "PriorityQueue.h"
#define SIZE 8
using namespace std;
PriorityQueue::PriorityQueue(){
_size = SIZE;
_next = 0;
_pqentry = new pqentry_t*[_size];
}
PriorityQueue::~PriorityQueue(){
delete[] _pqentry;
}
void PriorityQueue::insert(string value, float priority){
_pqentry[_next]->value = value; // this is probably not working
_pqentry[_next]->priority = priority;
_next++;
}
void PriorityQueue::printQueue(){
for (int i = 0; i < _next; i++){
cout << "Value: " << _pqentry[i]->value << endl
<< "Priority: " << _pqentry[i]->priority << endl;
}
cout << endl;
}
main.cpp
#include <iostream>
#include <string>
#include "PriorityQueue.h"
using namespace std;
int main()
{
PriorityQueue pq;
pq.insert("Banana", 23);
pq.printQueue();
}
I think, I know where the error is, in the PriorityQueue.cpp, here:
_pqentry[_next]->value = value;
_pqentry[_next]->priority = priority;
But I don't know what's wrong and I can't fix it. The compiler says there are no errors.
I hope, you can help me. Thanks in advance!
You did allocate the _pqentry member but you need to allocate each entry of this array as well, for example:
_pqentry[_next] = new pqentry_t;
before writing to it.
And do not forget to delete those :)
It looks like you are creating an array of pointers to pqentry_t in your constructor, but your insert method is expecting it to be an array of _pqentry structures themselves. You are not allocating space for the pqentry_t elements themselves and so when you try to dereference them in your insert method, the program crashes.
Try changing the definition of _pqentry in the class to pqentry_t *_pqentry and the allocation in the constructor to new pqentry_t[size]. This will allow your insert and printQueue methods to access the entries of _pqentry as they are written.

Having trouble writing stack implementation c++

I am building a programming language interpreter, and I am currently working on writing the stack code. Write now the stack will only hold byte values, but it will be extended to hold other bytes as well. At the moment I am having trouble with casting between 'BaseObject' that all my stack objects extend and my jbyte class. Here is my current test code.
#include "stdafx.h"
#include <string>
#include <stack>
#include <iostream>
#include <Windows.h>
#include <stack>
using namespace std;
class BaseObject
{
public:
virtual string getIdentifier(){return "Not Implemented";}
};
class Stack
{
class jbyte : public BaseObject
{
private:
INT8 byteValue;
public:
jbyte(INT8 value)
{
byteValue = value;
}
INT8 getValue()
{
return byteValue;
}
};
private:
stack<BaseObject> objectStack;
public:
void pushByte(INT8 byteValue)
{
jbyte toPush(byteValue);
objectStack.push(toPush);
}
INT8 popByte()
{
if(objectStack.size() == 0)
{
cout<<"ERROR: Trying To Pop Value From Empty Stack\nPress Any Key To Continue...";
_gettch();
exit(1);
}
else
{
BaseObject& bo = objectStack.top();
jbyte& b = dynamic_cast<jbyte&>(bo);
}
}
};
int main()
{
Stack stack;
stack.pushByte(9);
stack.popByte();
while(true);
}
When I try to run this however, I get an Unhandled exception at at 0x75C4C41F in StackTests.exe: Microsoft C++ exception: std::bad_cast at memory location 0x0034F858.
I would like to know how to fix this problem, or if that is difficult, how I could rewrite the stack to work successfully.
When you objectStack.push(toPush), the jbyte part of toPush is sliced off and only the BaseObject part remains. That's why casting the BaseObject back to jbyte is no longer possible.

"Warning: Can't find linker symbol for virtual table for value XXX value" using GCC and GDB (CodeBlocks)

I'm getting a runtime error ("memory can't be written") that, after inspection through the debugger, leads to the warning in the tittle.
The headers are the following:
componente.h:
#ifndef COMPONENTE_H
#define COMPONENTE_H
using namespace std;
class componente
{
int num_piezas;
int codigo;
char* proovedor;
public:
componente();
componente(int a, int b, const char* c);
virtual ~componente();
virtual void print();
};
#endif // COMPONENTE_H
complement.h implementation
#include "Componente.h"
#include <string.h>
#include <iostream>
componente::componente()
{
num_piezas = 0;
codigo = 0;
strcpy(proovedor, "");
//ctor
}
componente::componente(int a = 0, int b = 0, const char* c = "")
{
num_piezas = a;
codigo = b;
strcpy(proovedor, "");
}
componente::~componente()
{
delete proovedor;//dtor
}
void componente::print()
{
cout << "Proovedor: " << proovedor << endl;
cout << "Piezas: " << num_piezas << endl;
cout << "Codigo: " << codigo << endl;
}
teclado.h
#ifndef TECLADO_H
#define TECLADO_H
#include "Componente.h"
class teclado : public componente
{
int teclas;
public:
teclado();
teclado(int a, int b, int c, char* d);
virtual ~teclado();
void print();
};
#endif // TECLADO_H
teclado.h implementation
#include "teclado.h"
#include <iostream>
teclado::teclado() : componente()
{
teclas = 0;//ctor
}
teclado::~teclado()
{
teclas = 0;//dtor
}
teclado::teclado(int a = 0, int b = 0, int c = 0, char* d = "") : componente(a,b,d)
{
teclas = c;
}
void teclado::print()
{
cout << "Teclas: " << teclas << endl;
}
The main method where I get the runtime error is the following:
#include <iostream>
#include "teclado.h"
using namespace std;
int main()
{
componente a; // here I have the breakpoint where I check this warning
a.print();
return 0;
}
BUT, if instead of creating an "componente" object, I create a "teclado" object, I don't get the runtime error. I STILL get the warning during debugging, but the program behaves as expected:
#include <iostream>
#include "teclado.h"
using namespace std;
int main()
{
teclado a;
a.print();
return 0;
}
This returns "Teclas = 0" plus the "Press any key..." thing.
Do you have any idea why the linker is having troube with this? It doesn't show up when I invoke the virtual function, but before, during construction.
Two errors that I can see:
strcpy(proovedor, ""); // No memory has been allocated to `proovedor` and
// it is uninitialised.
As it is uninitialised this could be overwriting anywhere in the process memory, so could be corrupting the virtual table.
You could change this to (in both constructors):
proovedor = strdup("");
Destructor uses incorrect delete on proovedor:
delete proovedor; // should be delete[] proovedor
As this is C++ you should considering using std::string instead of char*.
If you do not change to std::string then you need to either:
Implement a copy constructor and assignment operator as the default versions are incorrect if you have a member variable that is dynamically allocated, or
Make the copy constructor and assignment operator private to make it impossible for them to be used.
Another source of this same message is that gdb can get confused by not-yet-initialized variables. (This answers the question title, but not the OP's question, since a web search led me here looking for an answer.)
Naturally, you shouldn't have uninitialized variables, but in my case gdb attempts to show function local variables even before they are declared/initialized.
Today I'm stepping through another developer's gtest case and this message was getting dumped to output every time the debugger stopped. In this case, the variable in question was declared on ~line 245, but the function started on ~line 202. Every time I stopped the debugger between these lines, I received the message.
I worked around the issue by moving the variable declaration to the top of the function.
For reference, I am testing with gdb version 7.11.1 in QtCreator 4.1.0 and I compiled with g++ version 5.4.1