so lets suppose i have this structure
struct CAddition {
int x;
int y;
int c;
int z[3];
int result() {
return x + y;
}
CAddition();
~CAddition();
};
CAddition::CAddition()
:x(0)
,y(2)
,z()
,c(result())
{
}
and now in the constructor I have initialized z which is an array member of the struct ,z() it output the initialized values with zeros , now when I try this other syntax
,z{}
and
,z{0,0,0}
they all output the same result
Is there a more efficient way to initialize an array in the constructor except the above two and is there any difference the 3 methods , I checked different websites for initialization they have used the either methods
If you want to initialize all elements in array with default value 0, using z{0} is very fast. Or if you want to initialize with the value -1, you can use memset() :
CAddition::CAddition()
:x(0)
,y(2)
,c(result())
{
memset(z, -1, 3 * sizeof(int));
}
Notice that, memset() works on bytes, not the number. If you need to fill array with a number , you can use fill_n() instead.
If by "more efficient way" you mean taking less time to construct CAddition, then no there isn't.
The fastest way to construct CAddition is to initialize the array to all zeros, which is the default behaviors.
It will take negligible amount of time for an array of 3 items, but it can take a long time if the size of the array is very large, in which case you'd be better off using std::vector and reserve some space instead.
Related
I have a double pointer Array of a structure:
typedef struct Position{
int x;
int y;
} Position;
Position** array = (Position**)malloc(sizeof(Position*)*10); //10 elements
array[0] = (Position*)malloc(sizeof(Position*));
array[0]->x = 10;
array[0]->y = 5;
Can I calculate the length of set array and if so, how?
The normal way for arrays does not work :
int length = sizeof(<array>)/sizeof(<array>[0]);
Once you have dynamically allocated an array, there is no way of finding out the number of elements in it.
I once heard of some hacky way to obtain the size of a memory block, (msize) which would allegedly allow you to infer the size of the data within the block, but I would advice against any such weird tricks, because they are not covered by the standard, they represent compiler-vendor-specific extensions.
So, the only way to know the size of your array is to keep the size of the array around. Declare a struct, put the array and its length in the struct, and use that instead of the naked array.
As you marked the question as C++, I would suggest that you use std::vector, then, after you "allocated some memory" (or requested some memory to allocated by std::vector constructor or by using push_back, or resize), you can simply get the size back using by using std::vector::size.
typedef struct Position{
int x;
int y;
} Position;
std::vector<Position> array(10);
array[0].x = 10;
array[0].y = 5;
size_t size = array.size(); // will be 10
Having only a pointer to some memory block, you cannot defer the size of this memory block. So you cannot defer the number of elements in it.
For arrays of pointers, however, you could infer the number of elements in it under the following conditions:
make sure that every pointer (except the last one) points to a valid object.
for the last pointer in the array, make sure that it is always NULL.
Then you can derive the length by counting until you reach NULL.
Maybe there are some other similar strategies.
Solely from the pointer itself, however, you cannot derive the number of elements in it.
Old question, but in case someone needs it:
#include <stdio.h>
...
int main()
{
char **double_pointer_char;
...
int length_counter = 0;
while(double_pointer_char[length_counter])
length_counter++;
...
return 0;
}
I have a static integer variable Game::numPlayers, which is read in as an input from user. I then have the following class defined as such:
class GridNode
{
private:
/* Members */
static const int nPlayers = Game::numPlayers;
std::vector<Unit> units[nPlayers];
//...
};
This won't compile ("in-class initializer for static data member is not a constant expression").
I obviously cant just assign the array size of Game::numPlayers, and I also tried not initializing it and letting a constructor do the work, but that didn't work either.
I don't understand what I'm doing wrong here and what else I could possibly do to get this to work as intended.
I'm just copying a value, how is that any different from static const int nPlayers = 8 which copies the value 8 into nPlayers and works?
Edit:
To clarify, I choose to have an array of vectors because I want each node to have a quick-access container of units, but one container for each user/player so as to distinguish which units belong to which player within each node (e.g. index 0 of the array = player 1, index 1 = player 2, index 2 = player 3, and so on), otherwise I would just have one vector or a vector of vectors. I thought a map might work, but I thought an array of vectors would be faster to access and push into.
Also, Game::numPlayers is read in as a user input, but only read and assigned once within one game loop, but if I close/restart/play a new game, it needs to read in the user input again and assign it once.
I don't see why you need to use an array of std::vector if the number of elements will be obtained at runtime.
Instead, create a std::vector<std::vector<Units>> and size it appropriately on construction. if you need to reset the size, have a member function resize the vector.
Example:
class GridNode
{
private:
/* Members */
std::vector<std::vector<Unit>> units;
public:
GridNode(int nPlayers=10) : units(nPlayers) {}
std::vector<Unit>& get_units(size_t player)
{ return units[player]; } // gets the units for player n
void set_num_players(int nPlayers)
{ units.resize(nPlayers); } // set the number of players
int get_num_players() const { return units.size(); }
};
int main()
{
int numPlayers;
cin >> numPlayers;
//...
GridNode myGrid(numPlayers); // creates a GridNode with
// numPlayers vectors.
//...
Unit myUnit;
myGrid.get_units(0).push_back(myUnit); // places a Unit in the
// first player
}
Also, it isn't a good idea to have extraneous variables tell you the vector's size. The vector knows its own size already by calling the vector::size() function. Carrying around unnecessary variables that supposedly gives you this information opens yourself up for bugs.
Only integral constant expressions are allowed as array sizes in array declarations in C++. A const int object initailized with something that is not an integral constant expression (your Game::numPlayers is not, since it is read from the user), does not itself qualify as integral constant expression.
The bottom line here is that regardless of how you slice it, it is not possible to sneak in a run-time value into an array declaration in C++. C++11 does support some semblance of C99-style Variable Length Arrays, but your case (a member array) is not covered by it anyway.
If the array size is a run-tuime value, use std::vector. In your case that would become std::vector of std::vectors.
I am trying to define a class. This is what I have:
enum Tile {
GRASS, DIRT, TREE
};
class Board {
public:
int toShow;
int toStore;
Tile* shown;
Board (int tsh, int tst);
~Board();
};
Board::Board (int tsh, int tst) {
toShow = tsh;
toStore = tst;
shown = new Tile[toStore][toStore]; //ERROR!
}
Board::~Board () {
delete [] shown;
}
However, I get the following error on the indicated line -- Only the first dimension of an allocated array can have dynamic size.
What I want to be able to do is rather then hard code it, pass the parameter toShow to the constructor and create a two-dimensional array which only contains the elements that I want to be shown.
However, my understanding is that when the constructor is called, and shown is initialized, its size will be initialized to the current value of toStore. Then even if toStore changes, the memory has already been allocated to the array shown and therefore the size should not change. However, the compiler doesn't like this.
Is there a genuine misconception in how I'm understanding this? Does anyone have a fix which will do what I want it to without having to hard code in the size of the array?
Use C++'s containers, that's what they're there for.
class Board {
public:
int toShow;
int toStore;
std::vector<std::vector<Tile> > shown;
Board (int tsh, int tst) :
toShow(tsh), toStore(tst),
shown(tst, std::vector<Tile>(tst))
{
};
};
...
Board board(4, 5);
board.shown[1][3] = DIRT;
You can use a one dimensional array. You should know that bi-dimensional arrays are treated as single dimensional arrays and when you want a variable size you can use this pattern. for example :
int arr1[ 3 ][ 4 ] ;
int arr2[ 3 * 4 ] ;
They are the same and their members can be accessed via different notations :
int x = arr1[ 1 ][ 2 ] ;
int x = arr2[ 1 * 4 + 2 ] ;
Of course arr1 can be seen as a 3 rows x 4 cols matrix and 3 cols x 4 rows matrix.
With this type of multi-dimensional arrays you can access them via a single pointer but you have to know about its internal structure. They are one dimensional arrays which they are treated as 2 or 3 dimensional.
Let me tell you about what I did when I needed a 3D array. It might be an overkeill, but it's rather cool and might help, although it's a whole different way of doing what you want.
I needed to represent a 3D box of cells. Only a part of the cells were marked and were of any interest. There were two options to do that. The first one, declare a static 3D array with the largest possible size, and use a portion of it if one or more of the dimensions of the box were smaller than the corresponding dimensions in the static array.
The second way was to allocate and deallocate the array dynamically. It's quite an effort with a 2D array, not to mention 3D.
The array solution defined a 3D array with the cells of interest having a special value. Most of the allocated memory was unnecessary.
I dumped both ways. Instead I turned to STL map.
I define a struct called Cell with 3 member variables, x, y, z which represented coordinates. The constructor Cell(x, y, z) was used to create such a Cell easily.
I defined the operator < upon it to make it orderable. Then I defined a map<Cell, Data>. Adding a marked cell with coordinates x, y, z to the map was done simply by
my_map[Cell(x, y, z)] = my_data;
This way I didn't need to maintain 3D array memory management, and also only the required cells were actually created.
Checking if a call at coordinate x0, y0, z0 exists (or marked) was done by:
map<Cell, Data>::iterator it = my_map.find(Cell(x0, y0, z0));
if (it != my_map.end()) { ...
And referencing the cell's data at coordinat x0, y0, z0 was done by:
my_map[Cell(x0, y0, z0)]...
This methid might seem odd, but it is robust, self managed regarding to memory, and safe - no boundary overrun.
First, if you want to refer to a 2D array, you have to declare a pointer to a pointer:
Tile **shown;
Then, have a look at the error message. It's proper, comprehensible English. It says what the error is. Only the first dimension of an allocated array can have dynamic size. means -- guess what, that only the first dimension of an allocated array can have dynamic size. That's it. If you want your matrix to have multiple dynamic dimensions, use the C-style malloc() to maintain the pointers to pointers, or, which is even better for C++, use vector, made exactly for this purpose.
It's good to understand a little of how memory allocation works in C and C++.
char x[10];
The compiler will allocate ten bytes and remember the starting address, perhaps it's at 0x12 (in real life probably a much larger number.)
x[3] = 'a';
Now the compiler looks up x[3] by taking the starting address of x, which is 0x12, and adding 3*sizeof(char), which brings to 0x15. So x[3] lives at 0x15.
This simple addition-arithmetic is how memory inside an array is accessed. For two dimensional arrays the math is only slightly trickier.
char xy[20][30];
Allocates 600 bytes starting at some place, maybe it's 0x2000. Now accessing
xy[4][3];
Requires some math... xy[0][0], xy[0][1], xy[0][2]... are going to occupy the first 30 bytes. Then xy[1][0], xy[1][1], ... are going to occupy bytes 31 to 60. It's multiplication: xy[a][b] will be located at the address of xy, plus a*20, plus b.
This is only possible if the compiler knows how long the first dimension is - you'll notice the compiler needed to know the number "20" to do this math.
Now function calls. The compiler little cares whether you call
foo(int* x);
or
foo(int[] x);
Because in either case it's an array of bytes, you pass the starting address, and the compiler can do the additional to find the place at which x[3] or whatever lives. But in the case of a two dimensional array, the compiler needs to know that magic number 20 in the above example. So
foo(int[][] xy) {
xy[3][4] = 5; //compiler has NO idea where this lives
//because it doesn't know the row dimension of xy!
}
But if you specify
foo(int[][30] xy)
Compiler knows what to do. For reasons I can't remember it's often considered better practice to pass it as a double pointer, but this is what's going on at the technical level.
Let's say I have an array arr. When would the following not give the number of elements of the array: sizeof(arr) / sizeof(arr[0])?
I can thing of only one case: the array contains elements that are of different derived types of the type of the array.
Am I right and are there (I am almost positive there must be) other such cases?
Sorry for the trivial question, I am a Java dev and I am rather new to C++.
Thanks!
Let's say I have an array arr. When
would the following not give the
number of elements of the array:
sizeof(arr) / sizeof(arr[0])?
One thing I've often seen new programmers doing this:
void f(Sample *arr)
{
int count = sizeof(arr)/sizeof(arr[0]); //what would be count? 10?
}
Sample arr[10];
f(arr);
So new programmers think the value of count will be 10. But that's wrong.
Even this is wrong:
void g(Sample arr[]) //even more deceptive form!
{
int count = sizeof(arr)/sizeof(arr[0]); //count would not be 10
}
It's all because once you pass an array to any of these functions, it becomes pointer type, and so sizeof(arr) would give the size of pointer, not array!
EDIT:
The following is an elegant way you can pass an array to a function, without letting it to decay into pointer type:
template<size_t N>
void h(Sample (&arr)[N])
{
size_t count = N; //N is 10, so would be count!
//you can even do this now:
//size_t count = sizeof(arr)/sizeof(arr[0]); it'll return 10!
}
Sample arr[10];
h(arr); //pass : same as before!
Arrays in C++ are very different from those in Java in that they are completely unmanaged. The compiler or run-time have no idea whatsoever what size the array is.
The information is only known at compile-time if the size is defined in the declaration:
char array[256];
In this case, sizeof(array) gives you the proper size.
If you use a pointer as an array however, the "array" will just be a pointer, and sizeof will not give you any information about the actual size of the array.
STL offers a lot of templates that allow you to have arrays, some of them with size information, some of them with variable sizes, and most of them with good accessors and bounds checking.
There are no cases where, given an array arr, that the value of sizeof(arr) / sizeof(arr[0]) is not the count of elements, by the definition of array and sizeof.
In fact, it's even directly mentioned (ยง5.3.3/2):
.... When applied to an array, the result is the total number of bytes in the array. This implies that the size of an array of n elements is n times the size of an element.
Emphasis mine. Divide by the size of an element, sizeof(arr[0]), to obtain n.
Since C++17 you can also use the standardized free function:
std::size(container) which will return the amount of elements in that container.
example:
std::vector<int> vec = { 1, 2, 3, 4, 8 };
std::cout << std::size(vec) << "\n\n"; // 5
int A[] = {40,10,20};
std::cout << std::size(A) << '\n'; // 3
No that would still produce the right value because you must define the array to be either all elements of a single type or pointers to a type. In either case the array size is known at compile time so sizeof(arr) / sizeof(arr[0]) always returns the element count.
Here is an example of how to use this correctly:
int nonDynamicArray[ 4 ];
#define nonDynamicArrayElementCount ( sizeof(nonDynamicArray) / sizeof(nonDynamicArray[ 0 ]) )
I'll go one further here to show when to use this properly. You won't use it very often. It is primarily useful when you want to define an array specifically so you can add elements to it without changing a lot of code later. It is a construct that is primarily useful for maintenance. The canonical example (when I think about it anyway ;-) is building a table of commands for some program that you intend to add more commands to later. In this example to maintain/improve your program all you need to do is add another command to the array and then add the command handler:
char *commands[] = { // <--- note intentional lack of explicit array size
"open",
"close",
"abort",
"crash"
};
#define kCommandsCount ( sizeof(commands) / sizeof(commands[ 0 ]) )
void processCommand( char *command ) {
int i;
for ( i = 0; i < kCommandsCount; ++i ) {
// if command == commands[ i ] do something (be sure to compare full string)
}
}
_countof(my_array) in MSVC
I can thing of only one case: the array contains elements that are of different derived types of the type of the array.
Elements of an array in C++ are objects, not pointers, so you cannot have derived type object as an element.
And like mentioned above, sizeof(my_array) (like _countof() as well) will work just in the scope of array definition.
It seems that if you know the type of elements in the array you can also use that to your advantage with sizeof.
int numList[] = { 0, 1, 2, 3, 4 };
cout << sizeof(numList) / sizeof(int);
// => 5
First off, you can circumvent that problem by using std::vector instead of an array. Second, if you put objects of a derived class into an array of a super class, you will experience slicing, but the good news is, your formula will work. Polymorphic collections in C++ are achieved using pointers. There are three major options here:
normal pointers
a collection of boost::shared_ptr
a Boost.Pointer Container
Let's say I have an array arr. When would the following not give the number of elements of the array: sizeof(arr) / sizeof(arr[0])?
In contexts where arr is not actually the array (but instead a pointer to the initial element). Other answers explain how this happens.
I can thing of only one case: the array contains elements that are of different derived types of the type of the array.
This cannot happen (for, fundamentally, the same reason that Java arrays don't play nicely with generics). The array is statically typed; it reserves "slots" of memory that are sized for a specific type (the base type).
Sorry for the trivial question, I am a Java dev and I am rather new to C++.
C++ arrays are not first-class objects. You can use boost::array to make them behave more like Java arrays, but keep in mind that you will still have value semantics rather than reference semantics, just like with everything else. (In particular, this means that you cannot really declare a variable of type analogous to Foo[] in Java, nor replace an array with another one of a different size; the array size is a part of the type.) Use .size() with this class where you would use .length in Java. (It also supplies iterators that provide the usual interface for C++ iterators.)
Use the Microsoft "_countof(array)" Macro. This link to the Microsoft Developer Network explains it and offers an example that demonstrates the difference between "sizeof(array)" and the "_countof(array)" macro.
Microsoft and the "_countof(array)" Macro
If you can not use C++17, which allows to use std::size(container), you can easily implement your own generic sizeofArray template function as a one-liner:
#include <cstddef>
#include <cstdio>
template< typename T, std::size_t N >
inline constexpr std::size_t sizeofArray( const T(&)[N] ) noexcept { return N; }
int x[10];
void* y[100];
long z[1000];
struct {int x; char y; long z;} s[123];
static_assert( sizeofArray(x) == 10, "error" );
static_assert( sizeofArray(y) == 100, "error" );
static_assert( sizeofArray(z) == 1000, "error" );
static_assert( sizeofArray(s) == 123, "error" );
int main() {
puts( "ok" );
}
test it here: http://cpp.sh/8tio3
It will work if and only if arr is a C-Array (type[size]; except for function parameters!), a reference to a C-Array (type(&)[size]) or a pointer to a C-Array (type(*)[size]).
Note you should use std::size or std::ssize instead with current C++-Standards!
In C++17 you can use std::size:
int arr[] = {1, 2, 3};
auto count = std::size(arr); // type std::size_t, value == 3
In C++20 you can additionally get a signed value by using std::ssize:
int arr[] = {1, 2, 3};
auto count = std::ssize(arr); // type std::ptrdiff_t, value == 3
https://en.cppreference.com/w/cpp/iterator/size
Also note that C++ unfortunately inherited from C that C-Arrays are never passed by value (deep copy) to functions.
void f(int a[3]);
is the same as
void f(int* a);
so you loose the information that a is an array and with this, how much elements it had. The 3 is completely ignored by the compiler!
If you want to preserve the datatype (including the array element count), you can use a pointer or a reference to an C-Array:
void f(int (&a)[3]); // reference to C-Array with 3 elements
void f(int (*a)[3]); // pointer to C-Array with 3 elements
void f(int a[3]); // pointer to int
void f(int* a); // pointer to int
If you want to call functions with Arrays call-by-value, you can use C++-Arrays (std::array) from the C++ standard library:
f(std::array<int, 3> a);
std::array<int, 3> arr = {1, 2, 3};
f(arr); // deep copy
https://en.cppreference.com/w/cpp/container/array
Determine how many numbers are in your array.
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n[10] ;
int l = sizeof(n)/sizeof(n[0]);
cout << l;
return 0;
}
I know is old topic but what about simple solution like while loop?
int function count(array[]) {
int i = 0;
while(array[i] != NULL) {
i++;
}
return i;
}
I know that is slower than sizeof() but this is another example of array count.
Suppose there is a structure such as:
struct XYZ
{
double a;
double b;
}
Now we make an object of it
struct XYZ abcd[10];
and now I am filling this array.
I have to initialize this array because I call this in a loop and it overwrites the previous values.
If it overwrites the previous 5 values by 4 new values then still the 5th one is still there in the array which results in the wrong output.
If you use c++ you can define a constructor, observe:
struct XYX {
double a, b;
XYX() { a=0; b=0; }
}
Initializing a struct is easily done by enumerating it's member values inside curly braces. Beware, though, 'cause if a member is omitted from the enumeration, it will be regarded as zero.
struct A { int a_, b_; };
A a = { 1, 2 };
A b = { 1 }; // will result in a_=1 and b_=0
A as [] = { {1,2}, {1,3}, {2,5} };
Strangely enough, this also works for the public members of an "aggregate" class. It's to be discouraged, though, since this way your class will lose it's ability to do the necessary things at construction time, effectively reducing it to a struct.
for (int i=0; i<10; ++i)
{
abcd[i].a = 0.0;
abcd[i].b = 0.0;
}
Of course, if some of the slots haven't been filled with meaningful data you probably shouldn't be looking at them in the first place.
If your question is how to initialize the array elements then #cemkalyoncu answer will help you.
If it over rites the previous 5 values
by 4 new values then still the 5th one
is still there in the array which in
result gives wrong output.
For this case it is better you go for vector.
You can remove the unwanted elements from the vector to make sure that it does not contain the wrong values.
In this case, remove 5th element from vector if you no longer use.
In addition to xtofl's answer, note, that if you want to zero-initialize the array, all you have to do is write
XYZ abcd[10] = {};
Also you can initialize with memset function
memset(&abcd[index], 0, sizeof(XYZ));