How to initialise struct with constant members with certain address? - c++

I am trying to initialise class object (which has constant members) with certain values and certain address. I understand that this is because members are constant but I need them to be constant. I tried to find solution but with no success.
So the question is: is there some "easy" way to do it?
class ints{
public:
const int a;
const int b;
ints(int a, int b);
};
ints::ints(int a, int b) :
a{a},
b{b}
{}
int main() {
auto ptr = (ints*)malloc(sizeof(ints));
ints values{1, 2};
// all wrong
// *ptr = ints copy{values};
// &values = ptr;
// *ptr = values;
std::cout << ptr->a; //ptr->a should be equal to 1
}

You can create an object at a specific address using placement-new:
extern void* some_address;
int main()
{
ints* ptr = new(some_address) ints{1, 2};
std::cout << ptr->a;
}

Related

I assigned a variable to the value of what is stored at a pointer's address, so why doesn't it change when the initial value does?

Basically, I just want to know why 'C' doesn't change when 'A' does. I'm guessing that it's because of the hierarchy, but I wanted to confirm and get an explanation as to why...
#include <iostream>
using namespace std;
class IntCell
{
public:
explicit IntCell( int initialValue = 0 )
{ storedValue = new int{ initialValue }; }
int read() const
{ return *storedValue; }
void write( int x )
{ *storedValue = x; }
private:
int *storedValue;
};
int main() {
IntCell a{ 2 };
IntCell* b = &a;
IntCell c;
int x = 10000;
int* y = &x;
cout << *y << endl;
c = *b;
a.write(4);
cout << a.read() << endl << c.read();
return 0;
}
I test your code and when you change "a", "c" change too.
Also You need to implement a copy constructor and assignment operator.
IntCell c; // you create a new instance with new memory address.
c = *b; // now this instance point to same memory as "a".
a.write(4); // so when you change "a", "c" change too.
In your case, the destructor is missing.
~IntCell(){
cout<<"deleting...\n";
delete storedValue;
}
You are using the implicitly-defined copy assignment. That is why c = *b; works. After the copy assignment, IntCell c and IntCell a both have the member which points to the same location. If a.write(4), c.read() will get the same value 4.

C++ object creation without constructor call

In c++, creating an object without calling a constructor like this. Does this count as defined behavior? (Disregard the unfreed heap memory)
class Foo {
public:
int *ptr;
int a, b;
Foo() { ptr = new int{}; }
~Foo() { delete ptr; }
void set(int a_, int b_) {a = a_; b = b_;}
void print() { std::cout << *ptr << a << b; }
};
int main() {
char *array[sizeof(Foo)]; // note the pointer
*((int**)array) = new int{3};
((Foo*)array)->set(1, 2);
((Foo*)array)->print(); // 312
}
You are building a memory block that can hold the data for the object, but that is not an object.
An object consist of potentially a lot more than that slice of memory, and what exactly more is up to the compiler. It could be nothing more, but it could be a lot of other things.

What is the best way to return reference to a constant sized array of pointers?

I have an array of pointers declared as a class member like this:
class Bar
{
private:
static constexpr int SIZE = 10;
Foo* m[SIZE];
}
In one of my class methods, I would like to return a pointer (or preferably, a reference) to this array. The array has a known size at compile time, but I am keeping track of how many items I have put in there (it is a buffer of stuff).
What is the best way to return a reference to this array in C++11 ?
Here are the things I have tried:
GetArray(Foo* &f[], unsigned &size) const
I like the syntax because it makes it clear that the reference value is an array of pointers, but this gives a compiler error: Declared as array of references of type Foo*
GetArray(Foo** &f, unsigned &size) const
{
f = m;
size = mSize;
}
Gives me: Error: assigning to Foo **' from incompatible type Foo *const[10]. Casting mFoo to (Foo**) alleviates the error, but IMHO, this is not elegant.
Nobody posted an answer using std::array yet, it is a very simple replacement:
class Bar
{
std::array<Foo *, 10> m;
public:
std::array<Foo *, 10> & getArray() { return m; }
std::array<Foo *, 10> const & getArray() const { return m; }
};
This seems to me a lot simpler than the hoops you have to jump through to use your C-style array version.
To avoid code duplication you could typedef std::array<Foo *, 10> FooArray; .
The technique of having both a const and a non-const implementation is a common pattern for accessor functions which return a reference or a pointer. (It's not required if your accessor returns by value, of course).
I would seek to use a std::array or a std::vector in most cases. If you are determined to use a raw array then you could go this way with it:
typedef int Foo;
typedef Foo* (&FooPtrArrayRef)[10]; // to make the syntax less hairy
class Bar
{
private:
Foo* m[10];
public:
// First way without using typedef
Foo* (&getArray())[10]
{
return m;
}
// Nicer looking way with a typedef
FooPtrArrayRef getArrayByRef()
{
return m;
}
};
int main()
{
Bar b;
Foo* (&array)[10] = b.getArray();
std::cout << (sizeof(array) / sizeof(Foo*)) << '\n';
// Alternative using "size deduction"
Foo* (&array2)[sizeof(b.getArray()) / sizeof(Foo*)] = b.getArray();
std::cout << (sizeof(array2) / sizeof(Foo*)) << '\n';
// MUCH nicer using the typedef
FooPtrArrayRef array3 = b.getArrayByRef();
std::cout << (sizeof(array3) / sizeof(Foo*)) << '\n';
}
The syntax is pretty obscure though.
The benefits of this is approach is that it retains the full type information of the array you are passing by reference. The obscure syntax is necessary to avoid the type collapsing to a Foo**. By retaining the full type of the array you retain the ability to know its size at compile time using the sizeof() operator.
here's another approach that returns the array reference and the current size as a tuple:
#include <tuple>
#include <functional>
#include <algorithm>
#include <iterator>
#include <iostream>
struct Foo {};
using FooBuffer = Foo*[10];
class Bar
{
public:
Bar()
: _m { nullptr }
{
_m[0] = new Foo;
_m[1] = new Foo;
_items = 2;
}
~Bar() {
for(auto fp : _m)
delete fp;
}
std::tuple<FooBuffer&, size_t> getInfo() {
return std::make_tuple(std::ref(_m), _items);
}
private:
Foo* _m[10];
size_t _items;
};
int main() {
Bar b;
auto info = b.getInfo();
FooBuffer& buf = std::get<0>(info);
size_t items = std::get<1>(info);
for(Foo** p = buf ; p != buf + items ; ++p) {
std::cout << "Foo at " << std::hex << *p << std::endl;
}
return 0;
}

C++ Pointer to struct member

If I were to make a struct, say:
struct FOO{
int x, y, z, a, b, c;
}
int main(){
FOO foo = {1, 2, 3, 4, 5, 6};
return 0;
}
Would there be anyway to create a pointer that can access FOO's integer members?
Maybe by making pointer that points to foo and then somehow modifying it to increment in integers?
I know that if I were to make FOO a class instead with a method that returns a pointer to the first int, then I could cycle though the members with ++ or [i](in a for loop). But I want to know if I can access structure members simply by knowing the address of the struct (assuming I have a good understanding of how to navigate said struct)
Any insight would be much appreciated.
Thanks!
You can overload operator[] for the struct:
struct bar // ALL_UPPERCASE is for macros!
{
int a, b, c, d, e, f;
int operator[](size_t i) const
{
switch(i)
{
case 0: return a;
case 1: return b;
case 2: return c;
case 3: return d;
case 4: return e;
case 5: return f;
default: assert(false);
}
}
};
Just a thought and this might not work, but you could try doing a pointer to the foo struct and then shifting the pointer by the size of an int for each element. So something like:
int * ptr= & foo;
ptr++;
If I'm remembering my hardware design class well enough a struct is actually really similar to an array in memory it can just have variable sized blocks of memory for each of its indices.
struct FOO{
int x, y, z, a, b, c;
} __attribute__ ((packed))
FOO foo;
int *i = &foo;
In this case, the attribute ((packed)) eliminates the problem created by padding, since it get's rid of it. Afterwards incrementing i, grantees that it will be in the next element of the struct.
It's pretty straightforward:
Foo foo = { 1, 2, 3, 4, 5, 6 };
int* pfoo = &foo.x;
int structMembers = sizeof(Foo) / sizeof(int);
for (int i = 0; i < structMembers; i++)
{
cout << pfoo[i] << endl;
}
There's no difference between a struct and class aside from default access modifier (private in structs, public in classes). Thus whatever you can do with classes, you can do with structs.
As I understood you need this: https://en.cppreference.com/w/cpp/utility/functional/mem_fn
if you need own implementation take this:
#include <iostream>
struct Foo
{
int a = 1;
char b = 'a';
};
template<typename Struct, typename var_type>
const var_type member_get( Struct& obj, var_type Struct::* mem_var ) { return
obj.*mem_var; }
int main()
{
Foo x;
std::cout << member_get( x, &Foo::a ) << std::endl;
std::cout << member_get( x, &Foo::b ) << std::endl;
return 0;
}

class::data_member vs class_object.data_member

I just saw a post in which I found something I never saw before, in short here it is:
class A {
public:
int _x;
};
void foo(A *a_ptr, int *m_ptr)
{
cout << (*a_ptr).*m_ptr << endl; // here
}
int main()
{
A a;
a._x = 10;
foo(&a, &A::_x); // and here
}
How could it be done? Pass in &A::_x, and later refer it using (*a_ptr).*m_ptr?
I thought, &A::_x will always refer to the same address, but different objects have different _x, how could it be done?
&A::_x is a pointer-to-member, which is not a pointer. Rather, think of it as some relative sort of construct which tells you where inside an object you find a particular member element. Only together with an instance reference can you locate the actual subobject of that instance which is given by the member pointer.
Compare:
struct Foo { int x; int y; };
Foo a = { 1, 2 };
Foo b = { 3, 4 };
Foo c = { 5, 6 };
int * p = &a.x; // ordinary pointer-to-int
int Foo::*pm = &Foo::x; // pointer-to-member
int result = a.*pm + b.*pm + c.*pm; // aggregate Foo::x
// point to a different member:
pm = &Foo::y;
result = a.*pm + b.*pm + c.*pm; // aggregate Foo::y