struct arraystack
{
int top;
int b;
int *c;
};
arraystack* s;
s->c[++s->top]=20;
How can we use pointer c as an array to put data in that??
You should allocate memory. So you have to know how many elements you will store at maximum.
s->c = new int[nb_elements]
If you don't know, you can allocate a certain amount of elements, and use realloc to increase size of array when it is full.
Also instead of using raw array, you should use vector
struct
{
...
std::vector<int> c;
}
Related
int main()
{
int arr[]={2,3,5,6,8};
int *ptr;
ptr=&arr[3];
cout<<ptr-arr;
}
Q.why the answer is 3 after compiling the code i.e. as it should be 3*sizeof(int) which in this case should be 3*4=12?
When you subtract pointers you get the distance between them, not the allocated size. The same goes for iterators in STL.
https://en.cppreference.com/w/cpp/language/operator_arithmetic#Additive_operators
The reason is that it is much easier to write correct code.
When the pointer difference between consecutive elements of an array is 1, then you can use ++p to walk through the array (assuming p is a pointer to an element). For example:
int a[10];
for (auto p = a, e = a + 10; p != e; ++p)
*p = 42;
Notice how the code does not have to deal with the size of the elements. If the array type changes from int to double, the code does not have to change and is still correct.
If I write in a function the following local variable:
Eigen::VectorXd v = Eigen::Vector2d(1.0,2.0);
Is v allocated on the stack or on the heap?
The object v itself is allocated on the stack and will contain one pointer and one Index variable. During the construction of v there will be additional 16 bytes allocated on the heap.
Simplified, something like this happens:
struct VectorXd {
double* data;
ptrdiff_t rows;
};
void foo(){
VectorXd v;
v.data = new double[2]; // actually uses an aligned malloc instead of new
v.rows = 2;
v.data[0] = 1.0; v.data[1] = 2.0;
// At destruction:
delete[] v.data;
}
To see what actually happens in your case, check out: https://godbolt.org/z/GYFmj0
For small objects you should almost always prefer to use fixed sized Vectors/Matrices, if you know the size at compile time.
Arrays require a constant to initialize the size. Hence, int iarr[10]
I thought I could possibly take a non-const argument and convert it to const then use it for an array size
int run(int const& size);
int run(int const& size)
{
const int csize = size;
constexpr int cesize = csize;
std::array<int, cesize> arr;
}
This, unfortunately doesn't work and I thought of using const_cast as
int run(int& size);
int run(int& size)
{
const int val = const_cast<int&>(size);
constexpr int cesize = val;
std::array<int, cesize> arr;
}
and this won't work either. I've read through a few SO posts to see if I can find anything
cannot-convert-argument-from-int-to-const-int
c-function-pass-non-const-argument-to-const-reference-parameter
what-does-a-const-cast-do-differently
Is there a way to ensure the argument is const when used as an initializer for the size of an array?
EDIT: I'm not asking why I can't initialize an array with a non-const. I'm asking how to initialize an array from a non-const function argument. Hence, initialize-array-size-from-another-array-value is not the question I am asking. I already know I can't do this but there may be a way and answer has been provided below.
std::array is a non-resizable container whose size is known at compile-time.
If you know your size values at compile-time, you can pass the value as a non-type template argument:
template <int Size>
int run()
{
std::array<int, Size> arr;
}
It can be used as follows:
run<5>();
Note that Size needs to be a constant expression.
If you do not know your sizes at compile-time, use std::vector instead of std::array:
int run(int size)
{
std::vector<int> arr;
arr.resize(size); // or `reserve`, depending on your needs
}
std::vector is a contiguous container that can be resized at run-time.
I'm asking how to initialize an array from a non-const function argument.
As you saw, it is not possible initialize an array size with an variable, because you need to specify the size or array at compiler time.
To solve your problem you should use std::vector that works like an array but you can resize it at run time. You can handle de vector as if you were handled an array, using the operator [], for example:
class MyClass
{
vector<char> myVector;
public:
MyClass();
void resizeMyArray(int newSize);
char getCharAt(int index);
};
MyClass::MyClass():
myVector(0) //initialize the vector to elements
{
}
void MyClass::resizeMyArray(int newSize)
{
myVector.clear();
myVector.resize(newSize, 0x00);
}
char MyClass::getCharAt(int index)
{
return myVector[index];
}
For more information check this link: http://www.cplusplus.com/reference/vector/vector/
Upgrade: Also, considere that std::array can't be resize, as this links say:
Arrays are fixed-size sequence containers: they hold a specific number of elements ordered in a strict linear sequence.
I have a data structure like this:
struct mystruct
{
float f;
int16_t i;
};
sizeof(int16_t) gives 2, but sizeof(mystruct) gives 8 instead of 6. Why is that? How can I declare an int16_t variable of 2 bytes inside my data structure?
That is because of padding, given your system's architecture, the compiler adds some space to the structure.
If you try to add another int16_t, you'll see that the size of this structure will still be 8.
struct mystruct
{
float f;
std::int16_t i;
std::int16_t g;
};
In your original case
struct mystruct
{
float f;
std::int16_t i;
//2 bytes padding
};
Note also that you can have padding in between members in the structure, that is why it is usually good advice to sort the members by decreasing order size, to minimize padding.
You can have a quick read at the corresponding wikipedia page, which is well written.
http://en.wikipedia.org/wiki/Data_structure_alignment#Typical_alignment_of_C_structs_on_x86
I have coded a program in C using MPI wherein the struct variable is to be sent in a ring fashion to the processes and, based on the value received from that variable, the work for that particular process is assigned.
The problem is I need to know how to to send a struct variable in the MPI_Send() function as it is giving INVALID DATATYPE at the runtime , Consider the following example
struct info{
int ne, n, u, v, process, min, strip, mincost, b;
} stat;
MPI_Send(&stat,sizeof(stat),sizeof(struct info),1,2,MPI_COMM_WORLD);
You have to do some operation before send a struct.
I wrote the code for your example but to understand better you should read some documentation.
Anyway, here some tips:
If you have a struct made of just one kind of elements, like in your example that all the vars are int, it's better to send a vector taking care the position of each variable.
If you had other kinds, you have to set count to 2 or more and change all the other arrays (e.g: array_of_types, array_of_blocklengths et cetera).
You can calculate the values of array_of_displaysments on your own in that case take care of the Data structure alignment.
If for example you have the struct that follows, x will start from 0 but y from 8, because a padding of 4 bytes will be add to align the elements. struct point{ int x; double y; };
If you don't want to calculate the array_of_displaysments always use MPI_Get_Address and do not rely on the & operator.
Here the code:
struct info{
int ne, n, u, v, process,min,strip,mincost,b;
}stat;
int main(...){
/*MPI INIT*/
struct info _info,
int count; //Says how many kinds of data your structure has
count = 1; //1, 'cause you just have int
// Says the type of every block
MPI_Datatype array_of_types[count];
// You just have int
array_of_types[0] = MPI_INT;
// Says how many elements for block
int array_of_blocklengths[count];
// You have 8 int
array_of_blocklengths[0] = {8};
/* Says where every block starts in memory, counting from the beginning of the struct. */
MPI_Aint array_of_displaysments[coun];
MPI_Aint address1, address2;
MPI_Get_address(&_info,&address1);
MPI_Get_address(&_info.ne,&address2);
array_of_displaysments[0] = address2 - address1;
/*Create MPI Datatype and commit*/
MPI_Datatype stat_type;
MPI_Type_create_struct(count, array_of_blocklengths, array_of_displaysments, array_of_types, &stat_type);
MPI_Type_commit(&stat_type);
// Now we are ready to send
MPI_Send(&_info, 1, stat_type, dest, tag, comm),
/* . . . */
// Free datatype
MPI_Type_free(&stat_type);
// MPI finalization
MPI_Finalize();
}
try this
MPI_Send(&stat,sizeof(struct info),MPI_CHAR,1,2,MPI_COMM_WORLD);
MPI_Recv(&data,sizeof(struct info), MPI_CHAR, 0, DEFAULT_TAG, MPI_COMM_WORLD, &status);
stat = (struct info *) data;