Pass array of struct pointers to function - c++

Trying to pass array of struct pointers to function doIt() . Looks my way is not correct since I can't get right second array element:
struct c {
int a;
char* b;
};
struct cc {
int a;
c* b;
};
char a[] = "aaa";
char b[] = "bbb";
char e[] = "eee";
c d1 = {1,a};
c d2 = {2,b};
c d3 = { 12,e };
cc g1 = { 123, &d1 };
cc g2 = { 321, &d2 };
cc g3 = { 333, &d3 };
void doIt( c * s)
{
cout << s->b;
s++;
cout << s->b;
}
What is right way to pass array of struct pointers?

Raw arrays in C (and C++) are just pointers. They point to the first element of an array. For example, if you want an array of int, you would write it like int* array. If you want an array of struct c, you would write it like c* array. If you want an array of pointers to struct c, you would write it like c** array.
To access elements, don't use array++, use array[i] where i is the index (position) of the element you want to access, 0 being the index of the first element, 1 the second, etc.
So, your code should look like this:
void doIt(c** s)
{
cout << s[0]->b; // s[0] is the first element
cout << s[1]->b; // s[1] is the second
}
Note that in C++, it is preferred to use std::vector instead of raw arrays.
void doIt(std::vector<c*> s)
{
cout << s[0]->b;
cout << s[1]->b;
}

If you want to pass array to a function you need also pass length of this array:
#include <iostream>
#include <vector>
struct c {
int a;
char* b = nullptr;
size_t size = 0;
};
void doIt(c* all, size_t length);
int main()
{
char a[] = "aaa";
const size_t sizeOfA = sizeof(a)/sizeof(a[0]);
char b[] = "bbb";
const size_t sizeOfB = sizeof(b)/sizeof(b[0]);
char e[] = "eee";
const size_t sizeOfE = sizeof(e)/sizeof(e[0]);
c d1 {1, a, sizeOfA};
c d2 {2, b, sizeOfB};
c d3 {12, e, sizeOfE};
c all[] = {d1, d2, d3};
const size_t length = sizeof(all)/sizeof(all[0]);
doIt(all, length);
return 0;
}
void doIt(c* all, size_t length)
{
if (!all)
{
std::cerr << "Pointer to array is null" << std::endl;
}
for (size_t i = 0; i < length; ++i)
{
for (size_t j = 0; j < all[i].size; ++j)
{
std::cout << all[i].b[j];
}
std::cout << std::endl;
}
}
You can use std::vector. So, you don't need to use adittional argument (length of the vector):
#include <iostream>
#include <vector>
#include <string>
struct c {
int a;
std::string b;
};
void doIt(const std::vector<c>& myVector);
int main()
{
std::vector<c> myVector;
myVector.emplace_back(1, "aaa");
myVector.emplace_back(2, "bbb");
myVector.emplace_back(12, "eee");
doIt(myVector);
return 0;
}
void doIt(const std::vector<c>& myVector)
{
for (size_t i = 0; i < myVector.size(); ++i)
{
std::cout << myVector[i].b << std::endl;
}
}

Related

initialize an array of object in c++ [duplicate]

This question already has an answer here:
Initializing an std::array of non-default-constructible elements?
(1 answer)
Closed 2 years ago.
I want to initialize a array of 1 million objects on stack, I need to write one million &i in the following code.
Is there any other good way.
#include <iostream>
class A{
public:
A(int* p)
: p_(p){
std::cout << "A" << std::endl;
}
private:
int *p_;
};
int main(){
int i;
A a[3] = {&i, &i, &i};
}
#include <iostream>
#include <type_traits>
class A{
public:
A(int* p)
: p_(p){
std::cout << "A" << std::endl;
}
private:
int *p_;
};
int main(){
using elemType = std::aligned_storage<sizeof(A), alignof(A)>::type;
const size_t count = 1000000;
int i;
elemType a[count];
for(int idx = 0; idx < count: ++idx) {
new (&a[idx]) A(&i);
}
...
for(int idx = 0; idx < count: ++idx) {
reinterpret_cast<A&>(a[idx]).~A();
}
return 0;
}
C++ new operator can be used to call constructor on a preallocated memory:
#include <iostream>
#include <cstddef>
#include <cstdint>
class A{
public:
A(int* p)
: p_(p){
std::cout << "A" << std::endl;
}
private:
int *p_;
};
int main(){
int i;
uint8_t buf[1000000 * sizeof(A)];
A* pa = reinterpret_cast<A*>(buf);
for (size_t n = 0; n < 1000000; n++) {
new (&pa[n]) A(&i);
}
return 0;
}
You could use std::vector and initialize is with a million elements
std::vector<A> a(1000000, &i);

How to alloc array of pointers to functions usinig new?

Suppose I have a pointer to pointer to function taking int and returning int*.
int* (**ptr)(int) //i hope i'm not wrong here
How should I alloc memory for that pointer using new? And how can I create an array of pointers to functions with new?
I was trying something like this:
int* (**ptr)(int) = new int* (*)(int);
but it shows "expected primary-expression before ‘)’ token"
Here is a demonstrative program that shows how the array can be declared with a typedef and without a typedef.
#include <iostream>
int * func1(int value)
{
static int x = value;
return &x;
}
int * func2(int value)
{
static int x = value;
return &x;
}
int * func3(int value)
{
static int x = value;
return &x;
}
int main()
{
const int N = 3;
typedef int * (*PFunc)(int);
PFunc *ptr = new PFunc[N] { func1, func2, func3 };
int* (**ptr1)(int) = new ( int* (*[N])(int) ){ func1, func2, func3 };
for (int i = 0; i < N; i++)
{
std::cout << *ptr[i]( i ) << std::endl;
}
std::cout << std::endl;
for (int i = 0; i < N; i++)
{
std::cout << *ptr1[i]( i ) << std::endl;
}
std::cout << std::endl;
return 9;
}
The correct syntax to create an array of functions pointers is as follows:
int* (**ptr)(int) = new (int*(*[5])(int));
This creates an array of 5 function pointers, where each function pointer is of type int *(*)(int).
This can be simplified with a typedef:
typedef int *(*fp)(int);
fp *ptr2 = new fp[5];

How do I pass a list of values to a function expecting an array?

In my program I want to pass a few variables into a function and have that function run a for loop to write the data to console.
This is my code:
void WriteValue(int[] arr)
{
for(auto c : arr)
std::cout<<arr<<std::endl;
}
int main()
{
int a = 0;
int b = 1;
int c = 3;
WriteValue(a,b,c);
return 0;
}
I know this would work in C# with params, but I don't have that option. How do I get this to run in C++?
Here's a very simple and flexible way:
#include <iostream>
template<typename T>
void WriteValue(const T& arr)
{
for(auto c : arr)
std::cout << c << std::endl;
}
int main()
{
int a = 0;
int b = 1;
int c = 3;
WriteValue(std::array<int, 3>{a,b,c});
// nicer C99 way: WriteValue((int[]){a,b,c});
return 0;
}
If you only want to be able to pass a list of ints (and it has to be a brace-separated list, not an existing array), you can instead do
#include <iostream>
#include <initializer_list>
void WriteValue(const std::initializer_list<int>& arr)
{
for(auto c : arr)
std::cout << c << std::endl;
}
int main()
{
int a = 0;
int b = 1;
int c = 3;
WriteValue({a,b,c});
return 0;
}
Unfortunately, VS2012 doesn't support this. You can upgrade to Visual 2013 (the Express Edition and Community Edition are both free), or you can use a helper variable:
#include <iostream>
template<typename T>
void WriteValue(const T& arr)
{
for(auto c : arr)
std::cout << c << std::endl;
}
int main()
{
int a = 0;
int b = 1;
int c = 3;
int args[] = { a, b, c };
WriteValue(args);
return 0;
}

How can I pass an array of objects?

Here I have a very simple program. My aim is to let b equal c, that is to copy all the content of c into b. But I don't know how. The getdata() function returns a pointer pointing to array of objects c, but how can it be used to put c into b?
#include<iostream>
#include<stdlib.h>
using namespace std;
class A
{
public:
A(int i,int j):length(i),high(j){}
int length,high;
};
class B
{
private:
A c[3] = {A(9,9),A(9,9),A(9,9)};
public:
A* getdata()
{
return c;
}
};
int main()
{
A b[3]={A(0,0),A(0,0),A(0,0)};
B *x = new B();
cout<< x->getdata() <<endl;
cout << b[1].length<<endl;
return 0;
}
In modern C++, make yourself a favor and use a convenient container class to store your arrays, like STL std::vector (instead of using raw C-like arrays).
Among other features, std::vector defines an overload of operator=(), which makes it possible to copy a source vector to a destination vector using a simple b=c; syntax.
#include <vector> // for STL vector
....
std::vector<A> v; // define a vector of A's
// use vector::push_back() method or .emplace_back()
// or brace init syntax to add content in vector...
std::vector<A> w = v; // duplicate v's content in w
That's a possible partial modification of your code, using std::vector (live here on codepad):
#include <iostream>
#include <vector>
using namespace std;
class A
{
public:
A(int l, int h) : length(l), high(h) {}
int length, high;
};
class B
{
private:
vector<A> c;
public:
const vector<A>& getData() const
{
return c;
}
void setData(const vector<A>& sourceData)
{
c = sourceData;
}
};
int main()
{
vector<A> data;
for (int i = 0; i < 3; ++i) // fill with some test data...
data.push_back(A(i,i));
B b;
b.setData(data);
const vector<A>& x = b.getData();
for (size_t i = 0; i < x.size(); ++i) // feel free to use range-for with C++11 compilers
cout << "A(" << x[i].length << ", " << x[i].high << ")\n";
}
Instead of creating an array of A i.e. 'b' in main, create a pointer to A. And then initialize it by calling the getdata().
A *b;
B *x = new B();
b = x->getdata();
Here is an example
#include <iostream>
#include <algorithm>
class A
{
public:
A( int i, int j ) : length( i ), high( j ){}
int length, high;
};
class B
{
private:
A c[3] = {A(9,9),A(9,9),A(9,9)};
public:
A* getdata()
{
return c;
}
};
int main()
{
A b[3] = { A(0,0), A(0,0), A(0,0) };
B *x = new B();
A *c = x->getdata();
std::copy( c, c + 3, b );
for ( const A &a : b ) std::cout << a.length << '\t' << a.high << std::endl;
delete []x;
return 0;
}
The output is
9 9
9 9
9 9
Instead of standard algorithm std::copy you may use an ordinary loop. For example
for ( size_t i = 0; i < 3; i++ ) b[i] = c[i];

How to declare the Char array of char variables already declared in class?

#include <stdio.h>
#include <iostream>
using namespace std;
//char* b[6] = new char[6];
char a[6] = {'b','c','d','e','f','g'};
char c[6] = {'a','b','d','d','f','g'};
int main()
{
char d[][6]={*a,*c};
for (int x = 0 ; x < 1; x++)
{
for(int y = 0; y<6; y++)
{
char test = d[x][y];
cout << test <<"\n";
}
}
return 0;
}
This code is C++ code. I am trying to create a class where it stores the char array. Then there is another char array of array storing already declared char variables. It compiles fine but it doesn't work out to as it should. It doesn't get me the right value that it should when the program tries to print the value
May be you meant array of pointers:
char *d[]={a,c};
typedef std::vector<char> VectorChar;
typedef std::vector< VectorChar* > VectorVectorChar;
struct V
{
V() : _v{ '0', '1', '2' } {}
VectorChar _v;
};
int main(void)
{
V arrV[5];
VectorVectorChar vvc;
for ( auto& v : arrV )
vvc.push_back( &v._v );
// print them
for ( auto pV : vvc )
{
for ( auto c : *pV )
cout << c << ' ';
cout << '\n;
}
return 0;
}
what i understood from the question that, you want to create class to store char array, which already initialized.
#include <stdio.h>
#include <iostream>
char a[6] = {'b','c','d','e','f','g'}; // Initialized character array. MAX 6
// This class will hold char array
class Test {
public:
void setName(char *name);
const char* getName();
private:
char m_name[6]; // MAX 6 ( since you already initialized(MAX 6), So no need dynamic memory allocation. )
};
void Test::setName(char *name) {
strcpy(m_name, name); // Copy, already initialized array
}
const char* Test::getName() {
return m_name;
}
int main(int argc, char** argv) {
{
Test foobar;
foobar.setName( a ); // set the pointer which point to starting of the initialized array.
cout << foobar.getName();
return 0;
}
char a[6] = {'b','c','d','e','f','\0'};
char c[6] = {'a','b','d','d','f','\0'};
char* d[]= {a,c};
for (int x = 0 ; x < 2; x++)
{
for(int y = 0; y < 6; y++)
{
char test = d[x][y];
cout << test << "\n";
}
}
return 0;