Nested struct with dynamic size in C++ - c++

I am trying to print data in showValues(mainStruct*) but I am unable to do so..
#include <iostream>
#include <string>
#include <vector>
#include <memory>
typedef struct
{
uint32_t someNumber;
}subStruct;
typedef struct{
uint32_t sizeofSubStruct;
subStruct subStructArray[1];
}mainStruct;
This function construct the mainStruct and fill it with some values
mainStruct* constructMainStruct()
{
mainStruct* msPtr;
msPtr = (mainStruct*)malloc(sizeof(mainStruct)*10);
msPtr->sizeofSubStruct = 10;
subStruct* ssPtr = msPtr->subStructArray;
for(uint32_t i=0; i < msPtr->sizeofSubStruct; i++)
{
ssPtr->someNumber = i+10;
ssPtr++;
}
return msPtr;
}
Following function does not print anything
void showValues(mainStruct* msPtr)
{
subStruct* ssPtr = msPtr->subStructArray;
for(uint32_t i=0; i < msPtr->sizeofSubStruct; i++)
{
std::cout << " - " + ssPtr->someNumber <<std::endl;
}
}
Main function
int main()
{
//contructing mainStruct with some values
mainStruct* msPtr = constructMainStruct();
//trying to print values which has been created in above step
showValues(msPtr);
}

Your printing problem (which is by no means the only issue) is in the line:
for(uint32_t i=0; i > msPtr->sizeofSubStruct; i++)
You initialize i to 0 but use a test of "i > msPtr->sizeofSubStruct;", it should be less-than rather than greater-than.
Other problems are with your allocation size, it should be sizeof(mainStruct)+sizeof(subStruct)*9, it's not a huge problem with the subStruct you have right now but as soon as subStruct becomes something complicated it would be.

Besides what #SoronelHaetir has already noticed, the function showValues is not incrementing the subStruct pointer.
The code should look like this;
void showValues(mainStruct* msPtr)
{
subStruct* ssPtr = msPtr->subStructArray;
for (uint32_t i = 0; i < msPtr->sizeofSubStruct; i++)
{
std::cout << " - " + ssPtr->someNumber << std::endl;
++ssPtr;
}
}

Following is the working code for showValues
void showValues(mainStruct* msPtr)
{
subStruct* ssPtr = msPtr->subStructArray;
for(uint32_t i=0; i < msPtr->sizeofSubStruct; i++)
{
std::cout << (ssPtr+i)->someNumber <<std::endl;
}
}
and complete program code is as below:
#include <iostream>
typedef struct
{
uint32_t someNumber;
}subStruct;
typedef struct{
uint32_t sizeofSubStruct;
subStruct subStructArray[1];
}mainStruct;
mainStruct* constructMainStruct()
{
mainStruct* msPtr;
msPtr = (mainStruct*)malloc(sizeof(mainStruct)*10);
msPtr->sizeofSubStruct = 10;
subStruct* ssPtr = msPtr->subStructArray;
for(uint32_t i=0; i < msPtr->sizeofSubStruct; i++)
{
ssPtr->someNumber = i+10;
ssPtr++;
}
return msPtr;
}
void showValues(mainStruct* msPtr)
{
subStruct* ssPtr = msPtr->subStructArray;
for(uint32_t i=0; i < msPtr->sizeofSubStruct; i++)
{
std::cout << (ssPtr+i)->someNumber <<std::endl;
}
}
int main()
{
//contructing mainStruct with some values
mainStruct* msPtr = constructMainStruct();
//trying to print values which has been created in above step
showValues(msPtr);
}

Related

how to update a variable in contiguous memory atomicly

I have a struct with multi variables packed which is not aligned.Then I make an array of the struct and set up a reader thread and a writer thread to update the variable concurrently.I find error value which only half of the variable is updated from output.I guess this is caused by one variable lay in two cache lines.Change the variable to atomic doesn't solve the problem.So,is there a way to solve this without memory aligned?
#include <thread>
#include <atomic>
#include <iostream>
#include <mutex>
#include <stdalign.h>
#pragma pack(1)
struct Foo {
uint64_t key;
uint64_t key2;
uint64_t key3;
uint32_t key4;
uint64_t key5;
};
#pragma pack()
const int block_size = 10;
uint64_t keys[10];
void printEle(const Foo* ele) {
std::cout << "Key " << ele->key
<< " key2 " << ele->key2
<< " key3 " << ele->key3
<< " key5 " << ele->key5 << std::endl;
}
void reader(Foo* list) {
for (int i = 0; i < 1000000; ++i) {
for (int j = 0; j < block_size; ++j) {
Foo* ele = reinterpret_cast<Foo*>(list + j);
printEle(ele);
}
}
}
void writer(Foo* list) {
for (int i = 0; i < 1000000; ++i) {
for (int j = 0; j < block_size; ++j) {
Foo* ele = reinterpret_cast<Foo*>(list + j);
if (i % 2 == 0) {
ele->key = keys[j];
ele->key2 = keys[j];
ele->key3 = keys[j];
ele->key5 = keys[j];
} else {
ele->key = j;
ele->key2 = j;
ele->key3 = j;
ele->key5 = j;
}
}
}
}
void test() {
keys[0]= 1556273083026830079;
keys[1]= 6541630416163430395;
keys[2]= 2310622570815837826;
keys[3]= 12643974306886634761;
keys[4]= 15393333677141345392;
keys[5]= 3591765785331799809;
keys[6]= 5404586990109662840;
keys[7]= 1376395845958874653;
keys[8]= 7620513273959825252;
keys[9]= 16620834775579010287;
Foo* list = new Foo[block_size];
for (int i = 0; i < block_size; ++i) {
uint64_t k = keys[i];
Foo* ele = reinterpret_cast<Foo*>(list + i);
ele->key = k;
ele->key2 = k;
ele->key3 = k;
ele->key4 = 707406378;
ele->key5 = k;
}
std::thread write(writer, list);
std::thread read(reader, list);
read.join();
write.join();
}
int main(int argc, char* argv[]) {
std::cout << "Size " << sizeof(Foo) << std::endl;
test();
std::cout << "done." << std::endl;
return 0;
}

Correct implementation of 2d vector population

I have a constructor and a method in an implementation file:
Boggle::Boggle(std::string boardString){
dim = sqrt(boardString.size());
vector<vector<char> > grid(dim, vector<char>(dim));
int co = 0;
for (int i = 0; i < dim; i++)
{
for (int j = 0; j < dim; j++)
{
grid[i][j] = boardString[co];
co++;
}
}
}
void Boggle::printMe() {
for (auto inner : grid)
{
for (auto item : inner)
{
cout << item << " ";
}
cout << endl;
}
}
The program executes, but doesn't do anything. As you can see I have sized my vector when I declared it. I believe the issue lies in my logic of assigning a character to a vector from a string perhaps.
As hinted in comments your vector grid is local to your function. You mostly likely wanted to use a class variable but ended up creating a local variable. You can use resize to set the dimensions of your grid. Also its better to ceil the sqrt to make sure that we are not missing any characters.
Example:
#include <stdio.h>
#include <vector>
#include <string>
#include <cmath>
#include <iostream>
using namespace std; // Avoid this
class Boggle{
public:
int dim;
vector<vector<char>> grid;
Boggle(string boardString);
void printMe();
};
Boggle::Boggle (std::string boardString)
{
dim = ceil(sqrt(boardString.size ()));
grid.resize(dim, vector <char>(dim));
int co = 0;
for (int i = 0; i < dim; i++) {
for (int j = 0; j < dim; j++)
{
grid[i][j] = boardString[co];
co++;
}
}
}
void Boggle::printMe ()
{
for (auto inner:grid) {
for (auto item:inner)
{
cout << item << " ";
}
cout << endl;
}
}
int main(){
Boggle boggle("hello world");
boggle.printMe();
return 0;
}
Result:
h e l l
o w o
r l d

How to print to the console after every swap using any sorting algorithm?

In my Intro to Computer Science class I am beginning to learn the basics of sorting algorithms. So far, we have gone over Bubble, Selection, and Insertion Sort.
After class today, the instructor has requested us to "enhance" the program by adding code to print out the vector/array after every swap during the sorting. I am at a complete loss as to how I would make this happen. I'm thinking something like :
if (swapped) { cout << vec << " "; }
but without even trying, I'm certain this wouldn't work. Any help is very much appreciated. Here's my code so far:
#include <string>
#include <cstdlib>
#include <ctime>
#include <vector>
#include <algorithm>
using namespace std;
vector<int> createVec(int n) {
unsigned seed = time(0);
srand(seed);
vector<int> vec;
for (int i = 1; i <= n; ++i) {
vec.push_back(rand() % 100 + 1);
}
return vec;
}
void showVec(vector<int> vec) {
for (int n : vec) {
cout << n << " ";
}
}
void bubbleSort(vector<int> &vec) {
int n = vec.size();
bool swapped = true;
while (swapped) {
swapped = false;
for (int i = 1; i <= n-1; ++i) {
if (vec[i-1] > vec[i]) {
swap(vec[i-1], vec[i]);
swapped = true;
}
}
}
}
void selectionSort(vector<int> &vec) {
int n = vec.size();
int maxIndex;
for (int i = 0; i <= n-2; ++i) {
maxIndex = i;
for (int j = i+1; j <= n-1; ++j) {
if (vec[j] < vec[maxIndex]) {
maxIndex = j;
}
}
swap(vec[i], vec[maxIndex]);
}
}
int main()
{
vector<int> numbers = createVec(20);
showVec(numbers);
cout << endl;
//bubbleSort(numbers);
selectionSort(numbers);
showVec(numbers);
return 0;
}
For example in the called function selectionSort substitute this statement
swap(vec[i], vec[maxIndex]);
for the following statement
if ( i != maxIndex )
{
swap(vec[i], vec[maxIndex]);
showVec( vec );
cout << endl;
}
Also the function showVec should declare the parameter as having a constant referenced type
void showVec( const vector<int> &vec) {
for (int n : vec) {
cout << n << " ";
}
}

accessing to value in two dimensional pointer array in c++

I want to declare two dimensional array with variable size.
I wrote the following code but something goes wrong!
int **p2DArray;
p2DArray = new int*[target_counter_new];
for (int i = 0; i < target_counter_new; ++i)
{
p2DArray[i] = new int[target_counter_old];
}
for(int i_oghli=0;i_oghli<target_counter_new;i_oghli++)
for(int j_oghli=0;j_oghli<target_counter_old;j_oghli++)
{
p2DArray[i_oghli][j_oghli]=i_oghli+10;
cout<<p2DArray[i_oghli][j_oghli];
}
what is problem here ?
#include <iostream>
using namespace std;
const int target_counter_new = 4;
const int target_counter_old = 4;
int main() {
int **p2DArray;
p2DArray = new int*[target_counter_new];
for (int i = 0; i < target_counter_new; ++i) {
p2DArray[i] = new int[target_counter_old];
}
for(int i_oghli=0;i_oghli<target_counter_new;i_oghli++) {
for(int j_oghli=0;j_oghli<target_counter_old;j_oghli++) {
p2DArray[i_oghli][j_oghli]=i_oghli+10;
cout<<p2DArray[i_oghli][j_oghli] << " ";
}
cout << endl;
}
// don't forget to delete the array
for (int i = 0 ; i < target_counter_new; ++i) {
delete [] p2DArray[i];
}
delete [] p2DArray;
return 0;
}
Check here : code
There doesn't appear to be any problem.

How to pass and return 3d array to a function in c++?

I have created a 3d array into main function because one of its size came from used input. I am using C++
std::cin >> size;
typedef int T[8][3];
T* tables = new T[size];
It is basically tables[size][8][3]
Now I have to use this 3d table in different functions and have to store values into it. The best way to do it by make this table as a global variable. But I am not sure that I can do it after main function. The other option I have, that I have to pass this table as a parameter and have to return that at the end of the function.
I have tried both the approach but I am having error. Please help me about this issue. I don't know which approach to choose and how to do it.
Thank you in advance.
**Example:**This an example what I really want to do. Here I create a 3d array in main function and through another function I gave some input into that array and again print that in main function.
#include <iostream>
#include <conio.h>
using namespace std;
class M
{
public:
int i,j,k;
public:
int pass(int (*table)[8][3],int size);
}
int M:: pass(int (*table)[8][3],int s)
{
for (i=0;i<s;i++)
{
//int a = tables[i][2][1];
for(j=0;j<8;j++)
{
for(k=0;k<3;k++)
{
table[i][j][k]=i;
}
}
}
return (*table)[8][3]; // not sure about this
}
int main()
{
int size,i,j,k;
std::cin >> size;
typedef int T[8][3]; // T is your 2d array type
T* tables = new T[size];
cout << "test";
M mx;
mx.pass(tables,size); // not sure
for (i=0;i<size;i++)
{
for(j=0;j<8;j++)
{
for(k=0;k<3;k++)
{
cout<<tables[i][j][k];
cout<<" ";
}
cout<<endl;
}
cout<<endl;
cout<<"..........." << i <<endl;
}
getch();
}
I don't know if I completely understand your problem. But you can definitely store the pointer locally in your object and reference it elsewhere. Something like this:
class M
{
public:
M(int(*tbl)[8][3]) : table(tbl) { }
int(*table)[8][3];
int i, j, k;
public:
void pass(int size);
};
void M::pass(int s)
{
for (i = 0; i<s; i++)
{
for (j = 0; j<8; j++)
{
for (k = 0; k<3; k++)
{
table[i][j][k] = i;
}
}
}
}
int main()
{
int size, i, j, k;
std::cin >> size;
typedef int T[8][3]; // T is your 2d array type
T* tables = new T[size];
cout << "test";
M mx(tables);
mx.pass(size); // not sure
for (i = 0; i<size; i++)
{
for (j = 0; j<8; j++)
{
for (k = 0; k<3; k++)
{
cout << tables[i][j][k];
// or you can also:
// cout << mx.table[i][j][k];
cout << " ";
}
cout << endl;
}
cout << endl;
cout << "..........." << i << endl;
}
_getch();
}
Since you are creating a dynamic 3D array whose two dimensions are fixed, Use a std::array<std::array<int, 3>, 8> as your 2D array. Use a std::vector<__2D_ARRAY_TYPE> to create the 3D array.
#include <iostream>
#include <array>
#include <vector>
int main() {
std::array<std::array<int, 3>, 8> array_2d ;
std::vector<decltype(array_2d)> array_3d ;
int size = 4 ;
for(int i = 0; i < size; ++i)
{
for(int j = 0; j < 8; ++j)
for(int k = 0; k < 3; ++k)
array_2d[j][k] = j + k ;
array_3d.push_back(array_2d);
}
return 0;
}
Something like this you can use easily which does the job more easily without any manual memory management.
You can pass it to a function. The signature would be :
return_type function_name(const std::vector<std::array<std::array<int, 3>, 8>>& array_3d)
{ .... }
In
class M
{
public:
int i,j,k;
public:
int pass(int (*table)[8][3],int size);
}
you don't have to write public twice. You can simply put all of the public member data under the keyword public.
Also, you seem to be re-writing your function over again at the very end. Instead of
cout<<tables[i][j][k];
You can write
cout<<*tables