Initialize C++ struct that contains a fixed size array - c++

Suppose I have a POD C struct as so:
struct Example {
int x;
int y[10];
int yLen;
}
With the following code, the program doesn't compile:
Example test() {
int y[10];
int yLen = 0;
auto len = this->getSomethingLength();
for (int i = 0; i < len; i++) {
y[yLen++] = this->getSomething(i);
}
return Example{ 0, y, yLen };
}
However, doing return {0, {}, 0}; does seem to compile. Problem is, I can't know the size of y until doing some sort of logic ahead of time. Initializing int y[10]{} in test doesn't seem to make a difference. I know this seems like a pretty simple question, but I can't seem to find anything that works.

Declare the structure as a whole instead of its parts and then initialize it:
Example test() {
Example result;
auto len = this->getSomethingLength();
for (result.yLen = 0; result.yLen < len; result.yLen++) {
result.y[result.yLen] = this->getSomething(result.yLen);
}
return result;
}
Declaring y as an int* and allocating memory with new, when the size is known, would be an even better solution.

Declare constructor in Example:
struct Example {
int x;
int y[10];
int yLen;
Example(int xNew, int *yNew, int yLenNew)
{
x = xNew;
yLen = yLenNew;
for (int i = 0; i < yLenNew; i++)
{
y[i] = yNew[i];
}
}
};
And use it like this:
Example test() {
int y[10];
int yLen = 0;
auto len = this->getSomethingLength();
for (int i = 0; i < len; i++) {
y[yLen++] = this->getSomething(i);
}
return Example( 0, y, yLen );
}

Related

Swapping elements in array doesn't work when using function pointer

So i want to use AscendingSort() and DecendingSort() as an argument but it seems like after return the value the swap part just get skipped, hope someone explain to me, thanks!.
bool AscendingSort(int a, int b)
{
return a > b;
}
bool DecendingSort(int a, int b)
{
return a < b;
}
void SortArray(int* a, int size, bool(*func)(int, int))
{
int saveElement;
for (int x = 0; x < size; x++)
{
for (int y = x + 1; y < size; y++)
{
if (func(a[x], a[y]))
{
saveElement = a[x];
a[x] == a[y]; //Those 2 lines getting skipped.
a[y] == saveElement;
}
}
}
}
void main()
{
int a[1000];
int arrSize;
SortArray(a, arrSize, AscendingSort);
};
You probably meant to use = operator instead of ==.

Get array from object in c++

This question might be simple but I never use raw pointers or arrays in C++ so...
I need to use a library function which looks like this:
void f(double a[3][3], double b[3], double c[3]);
a and b are used for input and the result is stored in c.
The computation of a is a bit complex but does never change so it makes sense to calculate it only once and save the result. In my program, I can link it to an object of type X.
class X{
public:
X(){
a = {{1,2,3},
{4,5,6},
{7,8,9}};
}
private:
double a[3][3];
}
How can I write a getter for X::a which can be used in function f?
This is how I would like to call function f:
#include "X.h"
int main(int argc, char *argv[]){
X o = X(); //create object
double a[3][3] = o.getA(); // I want to get a somehow
double b[3] = {1,2,3}; // create dummy b
double c[3] = {}; // create empty c
f(a,b,c); // call funktion to populate c
for(int i=0; i<3; ++i){
std::cout << c[i] << endl;
}
}
You know std::vector is the way to go for 2D arrays in C++, but if you can't bypass the obstacle you are facing, then it would be possible to pass the matrix as a parameter to the getter function, like this:
#include <iostream>
class X {
public:
void getA(double (&array)[3][3]) {
for (int i = 0; i < 3; ++i)
for (int j = 0; j < 3; ++j)
array[i][j] = a[i][j];
}
private:
double a[3][3] = {{1,2,3},
{4,5,6},
{7,8,9}};
};
int main(void) {
X o = X();
double a[3][3];
o.getA(a);
for(int i = 0; i < 3; ++i)
for(int j = 0; j < 3; ++j)
std::cout << a[i][j] << std::endl;
return 0;
}
This snippet should serve your purpose.
#include <iostream>
#include <string>
using namespace std;
class X {
public:
X() {
}
typedef double (*ptr_matrix)[3];
ptr_matrix getA(){
return a;
}
private:
double a[3][3] = {{ 1,2,3},
{4,5,6},
{7,8,9}};
};
void f(double a[3][3], double b[3], double c[3])
{
cout<<"Inside f function";
for(auto i = 0; i < 3;i++) {
cout<<endl;
for(auto j = 0 ; j < 3;j++)
cout<<a[i][j];
}
}
int main()
{
X o = X(); //create object
double (*a)[3] = NULL;
a = o.getA(); // I want to get a somehow
double b[3] = {0};
double c[3] = {0};
f(a,b,c);
}

Improper usage of new with inheritance?

I am trying to figure out a crash, and have boiled it down the following sample:
class Base
{
public:
virtual unsigned int GetNum () = 0;
};
class Derived : public Base
{
int data; // <--- commmenting this out removes the crash
public:
Derived() {}
virtual unsigned int GetNum() { return 1; }
};
void func() {
Base** ppBases;
unsigned int xLen = 3;
unsigned int yLen = 4;
ppBases = new Base*[xLen];
for(unsigned int x = 0; x < xLen; ++x) {
ppBases[x] = new Derived[yLen];
for(unsigned int y = 0; y < yLen; ++y) {
Base* curBase = dynamic_cast<Base*>(&(ppBases[x][y]));
Derived* curDerived = dynamic_cast<Derived*>(&(ppBases[x][y])); // <--- crashes with a null dereference
unsigned int result = curBase->GetNum();
result = result;
}
}
}
I guessed that Derived isn't actually being allocated with the proper size. Changing ppBases to be a tripple pointer (like so) makes everything work:
void func() {
Base*** ppBases;
unsigned int xLen = 3;
unsigned int yLen = 4;
ppBases = new Base**[xLen];
for(unsigned int x = 0; x < xLen; ++x) {
ppBases[x] = new Base*[yLen];
for(unsigned int y = 0; y < yLen; ++y) {
ppBases[x][y] = new Derived();
Base* curBase = dynamic_cast<Base*>(ppBases[x][y]);
Derived* curDerived = dynamic_cast<Derived*>(ppBases[x][y]);
unsigned int result = curBase->GetNum();
result = result;
}
}
}
I don't understand why though.
Thanks
The problem is with this line:
ppBases[x] = new Derived[yLen];
You're assigning an array of Derived objects to a Base * pointer. So when you write ppBases[x][y] the compiler works with the type of the pointer, which is Base *, and index appropriately. So ppBases[x][1] does not refer to the second Derived object in the allocated array.

Initializing an Array C++

My code is trying to implement the union-find algorithm and I have the id[] array and the sz[] array. I initialize them in the Union-Find constructor, but once I try to use those arrays in the methods within the Union-Find class, it changes all the array values to 1. I don't understand why. Is there something obvious that I'm missing??
H File
class UnionFind{
public:
UnionFind(int size);
void join(int x, int y);
int connected(int x, int y);
int find(int x);
private:
int size;
int id[];
int sz[];
};
CPP File
UnionFind::UnionFind(int size){
this->id[size] = id[size];
for(int i = 0; i < size; i++){
id[i] = i;
}
for(int i = 0; i < size; i++){
sz[i] = 1;
}
}
int UnionFind::find(int l){
//Path Compression Finding the Root
for(int i = 0; i < 5; i++){
}
while(l != id[l]){
id[l] = id[id[l]];
l = id[l];
}
return l;
}
void UnionFind::join(int x, int y){
int m = find(x);
int n = find(y);
if(sz[m] < sz[n]){
id[m] = n;
sz[n] += sz[m];
}
else{
id[n] = m;
sz[m] += sz[n];
}
}
int UnionFind::connected(int x, int y){
if(find(x) == find(y)){
return 1;
}
else{
return 0;
}
}
From the comments.
you can't have int id[] as a class member,
use std::vector (resize and fill in constructor),
your forgot to set member size in constructor,
your find algorithm uses path halving not path compression (this does not affect the running time).
Side note: you can use a single array/vector to implement your disjoint set data structure.

C++ pass an array of bitfields by reference

I'm trying put my map render (console, ASCII) to one function, but it don't compile.
It should be look like this:
struct tiles {
unsigned is_visible : 1;
//...
} tile[y][x];
void render_map(const tiles (tile&)[y][x]) {
for (int i = 0; i < y; i++) {
if (tile[y].is_visible == 0) {
//...
}
}
}
int main() {
render_map(tile);
//...
}
I try to do as in this answer: C++ pass an array by reference. (const tiles (tile&)[y][x])
Thanks to all, now it's work!
struct tiles {
unsigned is_visible : 1;
//...
} tile[y][x];
void render_map(const tiles (&tile)[y][x]) {
for (int i = 0; i < y; i++) {
for (int j = 0; j < x; j++) {
if (tile[i][j].is_visible == 0) {
//...
}
}
}
}
int main() {
render_map(tile);
//...
}
And i'll think about using vector.
Sorry for such stupid question :)
You could so something like this:
struct Tiles {
unsigned is_visible : 1;
//...
};
const int x = 5;
const int y = 5;
Tiles tiles[x][y];
void render_map(const Tiles tile[x][y]) {
for (int i = 0; i < y; i++) {
if (tile[y].is_visible == 0) { // tile is a 2d array, not a 1D, thus error
//...
}
}
}
int main() {
render_map(tiles);
//...
}
However, since this is C++, I don't see why you don't use a std::vector.
Also read this answer.
With a std::vector, you could do this for example:
void print_vector(std::vector< std:: vector<Tiles> >& v) {
for(unsigned int i = 0; i < v.size(); ++i)
for(unsigned int j = 0; j < v.size(); ++j)
j += 0;
}
int main() {
std::vector< std:: vector<Tiles> >v;
v.resize(2); // make space for two vectors of tiles
Tiles t;
t.is_visible = 0;
v[0].push_back(t);
v[1].push_back(t);
print_vector(v);
return 0;
}