what is the purpose of offset in c++? - c++

#include <iostream>
struct Vector {
float x, y, z;
};
int main() {
size_t offset = (long)&((Vector*)nullptr)->x;
std::cout << offset << std::endl;
std::cout << (int)offsetof(struct Vector,y) << std::endl;
std::cout << (int)offsetof(struct Vector,z) << std::endl;
return 0;
}
What does offset of a struct member exactly means and what is its purpose?
I have tried with some online resources and I could get it.Off
Explain how offset exaclty works with this code!

Related

c++11 - zero-initi of members insted of default-init

In the below code, I expect members of a being inited with gargabe as they are not mentioned in the members-init-list of the called constructor (with two int parameters). Instead, I'm constantly getting 0 in both i and j of a, b and c and I am failing to see why. Could anybody please point me in the right direction?
#include <iostream>
#include <type_traits>
class A {
public:
int i;
int j;
A() = delete;
A(int a, int b) { std::cout << "VOLOLO!" << std::endl; };
};
int
smear_stack(int p)
{
int j = p++;
int a[500] = {};
for(int i = 0; i < 499; i++) {
a[i] = ++j;
}
std::cout << j << std::endl;
return ++j;
}
int main(void)
{
int i = 2;
i = smear_stack(++i);
A a (i, 32 );
std::cout << "a is " << a.i << " " << a.j << std::endl;
A b = { a };
std::cout << "b is " << b.i << " " << b.j << std::endl;
A c = { a.i, a.j };
std::cout << "c is " << c.i << " " << c.j << std::endl;
}
The i and j fields that you are accessing are, indeed, uninitialized. However, you are smearing the wrong part of the stack. It just so happens that on most OSes, the stack is initially all zeros. It even used to be common in C (long ago) to assume that automatic variables in main were zero-initialized.
To see that the memory is indeed uninitialized, it suffices to put something else there. Here's an example:
#include <iostream>
#include <memory>
class A {
public:
int i;
int j;
A() = delete;
A(int a, int b) { std::cout << "VOLOLO!" << std::endl; };
};
union U {
int is[2];
A a;
U() : is{3,4} {}
};
int
main()
{
U u;
std::construct_at(&u.a, 5, 6);
std::cout << u.a.i << ", " << u.a.j << std::endl;
// output:
// VOLOLO!
// 3, 4
}

Pass reference of array of objects to function

I'm trying to change a parameter of an object inside an array, but it seems like it's creating a new one when I pass it to the function.
I already saw similar questions and answers like this one, but it doesn't work for me, because I don't have a fixed array size in the final code.
I created a very short version of the code to show the problem.
#include <iostream>
using namespace std;
class Vect {
public:
Vect(int x, int y)
{
_x = x;
_y = y;
}
int _x;
int _y;
};
void ChangeX(Vect tests[], int size)
{
for (int i = 0; i < size; i++) {
tests[i]._x = 39;
}
}
int main()
{
Vect v1 = Vect(1,2);
Vect v2 = Vect(6,3);
cout << "Initial X: ";
cout << v1._x;
cout << "\n";
Vect vectors[2] = { v1, v2 };
cout << "Final X: ";
ChangeX(vectors, 2);
cout << v1._x;
return 0;
}
I expect the output to be:
Initial X: 1
Final X: 39
But in reality is:
Initial X: 1
Final X: 1
Also, using C++ vectors is not the solution for now. I'm running low on program memory usage and have a very small space for extra code.
Your issue has nothing to do with your function. It is updating the contents of the array correctly. There is no need to pass the array itself by reference.
The real problem is with the array itself. The statement Vect vectors[2] = {v1, v2}; makes copies of the v1 and v2 objects in the array. Your function is modifying the copies, and then afterwards you output values from the originals instead of the copies. So, your output does not change, since the function is not modifying the originals.
To accomplish what you are attempting, pass in an array of pointers instead, where the pointers are pointing at the original objects, not copies of them, eg:
#include <iostream>
class Vect {
public:
Vect(int x, int y){
_x = x;
_y = y;
};
int _x;
int _y;
};
void ChangeX(Vect* tests[], int size){
for(int i = 0; i < size; i++){
tests[i]->_x = 39;
}
}
int main()
{
Vect v1(1,2);
Vect v2(6,3);
std::cout << "Initial X:\n";
std::cout << v1._x << "\n";
std::cout << v2._x << "\n";
Vect* vectors[2] = {&v1, &v2};
ChangeX(vectors, 2);
std::cout << "Final X:\n";
std::cout << v1._x << "\n";
std::cout << v2._x << "\n";
return 0;
}
Live Demo
Otherwise, start out with an array to begin with, eg:
#include <iostream>
class Vect {
public:
Vect(int x, int y){
_x = x;
_y = y;
};
int _x;
int _y;
};
void ChangeX(Vect tests[], int size){
for(int i = 0; i < size; i++){
tests[i]._x = 39;
}
}
int main()
{
Vect vectors[2] = {Vect(1,2), Vect(6,3)};
std::cout << "Initial X:\n";
std::cout << vectors[0]._x << "\n";
std::cout << vectors[1]._x << "\n";
ChangeX(vectors, 2);
std::cout << "Final X:\n";
std::cout << vectors[0]._x << "\n";
std::cout << vectors[1]._x << "\n";
return 0;
}
Live Demo

Struct Values inside Vector Become Corrupted when Passed by Value

I have the following simple struct:
struct Wire {
int start_x;
int end_x;
int start_y;
int end_y;
Wire(int sx, int ex, int sy, int ey): start_x(sx), end_x(ex), start_y(sy), end_y(ey) {}
};
I also have the following print functions that take a std::vector<Wire> and print out some values from the first item:
These functions are indentical apart from the fact that one takes arguments by value and the other by reference.
void print_first_wire_value(std::vector<Wire> wires){
std::cout << "(" << wires[0].start_x << ", " << wires[0].start_y << ")" << std::endl;
}
void print_first_wire_reference(std::vector<Wire> &wires){
std::cout << "(" << wires[0].start_x << ", " << wires[0].start_y << ")" << std::endl;
}
My main function includes the following code.
It populates a vector with wire objects using another function. It then calls both of the print functions.
std::vector<Wire> wires = input_to_wires(first_line);
std::cout << "By value: " << std::endl;
print_first_wire_value(wires);
std::cout << "By reference: " << std::endl;
print_first_wire_reference(wires);
I know for a fact the first start_x and end_x values are 0 and 0. Both print functions should print these values. But bizarrely I instead get this:
By value:
(-543694264, -543694264)
By reference:
(0, 0)
What on earth is going on here?
Minimum Reproducible Example
(Please excuse the seemingly strange names, this is the start of a solution to a programming challenge from advent of code).
day3_lib.h
#pragma once
#include <vector>
#include <string>
struct Wire{
Wire(int sx, int ex, int sy, int ey);
};
std::vector<Wire> populate_wires();
void print_first_wire_value(std::vector<Wire> wires);
void print_first_wire_reference(std::vector<Wire> &wires);
day3_lib.cpp
#include <vector>
#include <sstream>
#include <iostream>
#include <stdexcept>
struct Wire {
int start_x;
int end_x;
int start_y;
int end_y;
Wire(int sx, int ex, int sy, int ey): start_x(sx), end_x(ex), start_y(sy), end_y(ey) {}
};
std::vector<Wire> populate_wires(){
std::vector<Wire> wires;
Wire wire1(0, 0, 1003, 0);
Wire wire2(1003, 0, 1003, -138);
Wire wire3(1003, 0, 662, -138);
wires.push_back(wire1);
wires.push_back(wire2);
wires.push_back(wire3);
return wires;
}
void print_first_wire_value(std::vector<Wire> wires){
std::cout << "(" << wires[0].start_x << ", " << wires[0].start_y << ")" << std::endl;
}
void print_first_wire_reference(std::vector<Wire> &wires){
std::cout << "(" << wires[0].start_x << ", " << wires[0].start_y << ")" << std::endl;
}
day3.cpp
#include "./day3_lib.h"
#include <fstream>
#include <iostream>
int main(){
std::vector<Wire> wires = populate_wires();
std::cout << "By value: " << std::endl;
print_first_wire_value(wires);
std::cout << "By reference: " << std::endl;
print_first_wire_reference(wires);
}

How set value in constant into struct c++

I can not assign a value to a constant within a structure, follow the code:
#include <iostream>
#include <stdio.h>
typedef struct
{
float a;
float b;
float c;
float intensity;
} PointXYZI;
typedef struct structParent{
int x;
int y;
const PointXYZI* xyzi;
} structParent;
int main()
{
float o = 10.f, p = 5.0f, z = 96.0f;
PointXYZI points = {o, p, z};
const structParent *data = {0,0, &points};
std::cout << " *-* " << data.xyzi->c << std::endl;
std::cout << " *-* " << points.a << std::endl;
return 0;
}
I get the following error with this code:
error: scalar object ‘data’ requires one element in initializer const structParent *data = {0,0, &points};
Thank you...
An explained by example version of #UnholySheep's answer is the following.
void someFunc(const structParent &x)
// ^^^^^^
{
std::cout << " #_# " << x.xyzi->c << std::endl;
}
int main()
{
float o = 10.f, p = 5.0f, z = 96.0f;
PointXYZI points = {o, p, z, 0};
// ^^^^^
const structParent data = {0,0, &points};
// ^^^
std::cout << " *-* " << data.xyzi->c << std::endl;
std::cout << " *-* " << points.a << std::endl;
someFunc(data);
// ^^^^^^^
return 0;
}

C++ Unexpected number output

EDIT: Fixed the problem thanks to advice from below. Changed the return type of evaluation() from an int to a void.
I'm learning how to use classes, and I'm experiencing a problem. I keep getting an output that says:
0
They are not equal.
4469696
Where is that last number coming from? It should be somewhere after
the line
std::cout << Thing.evaluation(Thing.getValue()) << std::endl;
but I don't see anything that could possibly be outputting that value. Is it memory leakage?
#include <iostream>
#include <conio.h>
class classTest
{
public:
int equivalency(int x, int y)
{
if (x == y)
{
value = 1;
} else
{
value = 0;
}
}
int evaluation(int z)
{
if (z == 0)
{
std::cout << "They are not equal." << std::endl;
} else
{
std::cout << "They are equal." << std::endl;
}
}
int getValue()
{
return value;
}
private:
int value;
};
int main()
{
int a = 0, b = 0;
classTest Thing;
std::cout << "Enter two numbers for comparison." << std::endl;
std::cin >> a >> b;
Thing.equivalency(a, b);
std::cout << Thing.getValue() << std::endl;
std::cout << Thing.evaluation(Thing.getValue()) << std::endl;
getch();
return 0;
}
In evaluation() you print the expected messages. Then you don't return anything from this function although it is declared to return int, i.e., you get undefined behavior. Further more, you actually point the random result since you output the result of the call:
std::cout << Thing.evaluation(Thing.getValue()) << std::endl;
BTW, don't use std::endl! If you want a newline, use '\n', if you want to flush the buffer use std::flush. Unnecessary use of std::endl is a relatively frequent source of major performance problems.