C++ possible #define something but used before - c++

I am wondering if this is possible (for very easy use in project)
Say:
// array size (COUNT)
int foo[COUNT];
// values
foo[0] = 1;
foo[1] = 43;
foo[2] = 24;
// define (or equivalent) its size at the end
#define COUNT 3
(This is by design, so I don't have to fine tune it whenever I change the arrays length)
Thanks.
Edit:
What I am looking for is defining the size of the array after it has been filled with values. In the example I only know that it is 3 when I put values. So I could add 4 more "foo"s and only need to change the #define below.
Next Edit:
// this is the idea, can this be possible? or even a "forward" declared
int foobar = THEVALUE
// way further down
#define THEVALUE 5;

int foo[] = {1, 43, 24};
int const count = 3; // See the SO array FAQ for how to compute this.
A simple type safe way to compute size, not mentioned in the SO array FAQ (because it was written before C++11), is
int const count = end( foo ) - begin( foo );
where end and begin are the std namespace functions from the <iterator> header.
See the SO array FAQ for other ways.
Generally, in modern C++ it is preferable to use std::array (fixed size) and std::vector (dynamic size) over raw arrays. This is safer and with more rich functionality, including in particular assignment and the ability to check the size easily. Unfortunately std::array does not support a size inferred from the initializer, so in this you'd have to use std::vector even if the array size is meant to be constant:
vector<int> foo = {1, 43, 24};
// foo.size() gives you the size at any moment.

You could initialize array with initializer list, then you don't need to know its size at all:
int foo[] = { 1, 43, 24 }
int size = sizeof(foo) / sizeof(int); // if you do need to know size
EDIT:
For a more idiomatic C++11 see the answer above :)

Related

How to dynamically create a c++ array with known 2nd dimension?

I have a function:
void foo(double[][4]);
which takes a 2d array with 2nd dimension equal to 4. How do I allocate a 2d array so that I can pass it to the function? If I do this:
double * arr[4];
arr = new double[n][4];
where n is not known to the compiler. I cannot get it to compile. If I use a generic 2d dynamic array, the function foo will not take it.
As asked, it is probably best to use a typedef
typedef double four[4];
four *arr; // equivalently double (*arr)[4];
arr = new four[n];
Without the typedef you get to be more cryptic
double (*arr)[4];
arr = new double [n][4];
You should really consider using standard containers (std::vector, etc) or containers of containers though.
typedef double v4[4];
v4* arr = new v4[n];
Consider switching to arrays and vectors though.
I know it may not be what OP has intended to do, but it may help others that need a similar answer.
You are trying to make a dynamic array of statically success array. The STL got your solution: std::vector and std::array
With these containers, things are easy easier:
std::vector<std::array<int, 4>> foo;
// Allocate memory
foo.reserve(8);
// Or instead of 8, you can use some runtime value
foo.reserve(someSize);
// Or did not allocated 8 + someSize, but ensured
// that vector has allocated at least someSize
// Add entries
foo.push_back({1, 2, 3, 4});
// Looping
for (auto&& arr : foo) {
arr[3] = 3;
}
// Access elements
foo[5][2] = 2;
Alternatively to creating a new type and occupying a symbol, you can create a pointer to pointer, and do it like that:
double **arr = new double*[j];
for (int i = 0; i < j; ++i)
{
arr[i] = new double[4];
}
whereas j is the int variable that holds the dynamic value.
I've written a simple code that shows it working, check it out here.

Size of dynamic array or loop through it without knowing size

Like in title, can I somehow get size of dynamic allocated array (I can't keep it separately), or somehow loop through this array without using it's size?
int *ar=new int[x]; //x-size of array, I don't know it in the beggining,
P.S. If I wanted to use std::vector, I wouldn't ask about it, so don't tell me to use it :)
A std::vector is designed for this.
If you can't use a std::vector I can see a couple of options.
1) Use an array terminator.
If your array should only contain positive numbers (for example) or numbers within a given range then you can use an illegal value (eg -1) as an array terminator.
for(int* i = arr; *i != -1; ++i)
{
// do something with *i
}
2) Embed the length in the array.
For a numeric array you could, by convention, store its length in the first element.
for(int i = 0; i < arr[0]; ++i)
{
// do something with arr[i + 1]
}
If you want to store the size your dynamic array inside it, well, just do so:
#include <iostream>
#include <cstdint>
#include <cstddef>
using std::size_t;
struct head_t { size_t size; int data[]; };
int main() {
head_t* h = static_cast<head_t*>(::operator new(sizeof(head_t) + 10 * sizeof(int)));
h->size = 10;
int* my_10_ints = h->data;
// Oh noez! I forgot 10!
size_t what_was_10_again = static_cast<head_t*>(static_cast<void*>(my_10_ints) - offsetof(head_t, data))->size;
::std::cout << what_was_10_again << "\n";
::operator delete(static_cast<void*>(my_10_ints) - offsetof(head_t, data));
}
You can even put that functionality in a libraryesque set of functions! Oh, and once you do that you realize you could just have an unordered_map that maps pointers to sizes. But that would be like using vector: Totally boring.
No. That's one reason everybody uses containers. If std::vector doesn't please you, you can make a container of your own.
Edit: Since dynamic array size is determined at runtime, someone must store the size somewhere (unless you're willing to use a sentry value). Not even the compiler can help, because the size is determined in runtime.

Dynamic memory allocation...how about this type of inititlization?

To create an integer on heap and initialize it to a value 5, we do:
int* a = new int(5);
To create an array of 5 integers on the heap, we do:
int* a = new int[5];
But, if we want to create an array of 5 integers and initialize each of them to 10 in one single instruction, is it possible?
To make things more interesting, let us say that the array size will only be known at run time. How about then?
Also, I know this is a very trivial question, but I'm making this transition from Java and get confused at times with C++, so... if not initialized during declaration, then unlike in Java, C++ primitive data types are not initialized with default values, and contain garbage values, right?
But someone told me that if they are declared as global variables, then they are initialized to default values like in Java...is that true as well? Why?
I prefer:
std::vector<int> a = {10,10,10,10,10};
C++ is a very complex language, with many different (even contradicting) goals.
One of the ideas behind it was that you should not pay in efficiency what you don't need and this is what is behind the concept of uninitialized values.
When you write
int x;
the variable x is initialized if it's at global/namespace scope and instead is not initialized when the definition is in a local scope.
This happens not because who designed C is crazy (of course an initialized value is better) but because initialization at global/namespace scope is free from an efficiency point of view as it's done compile/link/loading time, not at runtime.
Initializing a variable in local scope instead has a cost (small, but non-zero) and C++ inherited from C the idea that shouldn't pay for it if you don't need it, thus if you want your variable initialized to any value simply says so with:
int x = 42;
Note however that an uninitialized variable is not simply "containing a garbage value", it's uninitialized and you are not allowed to read its content as such an operation is "undefined behavior".
There are platforms in which just reading the content of an uninitialized variable may crash ("trap representations": for example hardware with dedicated registers for pointers in which just placing an invalid address in a register - not doing anything with it - provokes an hardware exception).
No, it is not possible to allocate an array with new[] and specify an initial value for the array elements. You have to fill in the array after the allocation is finished, eg:
int count = 5;
int* a = new int[count];
for (int i = 0; i < count; ++i)
a[i] = 10;
...
delete[] a;
That is not very C++-ish. You could use std::fill() to get rid of the loop, at least:
int count = 5;
int* a = new int[count];
std::fill(a, a+count, 10);
...
delete[] a;
A better option is to switch to a std::vector instead, which has a constructor that does exactly what you are looking for:
std::vector<int> a(5, 10); // create 5 elements initialized to value 10
std::vector has a constructor where you can specify the initial size and initial value:
std::vector<int> an_array(size, init_value);
If you want to use a dynamic array using new[], you have to assign the initial value to each element:
int* array = new a[size];
for(int i = 0; i < size; ++i)
array[i] = init_value;
...
delete[] array;
Use std::array if the size is known at compile-time:
std::array<int, 5> myArray = { 1, 2, 3, 4, 5 };
Which is RAII-conform and safe.
You just have to include <array> and <initializer_list>.
In other cases, use std::vector.
This works for me with g++ 4.8.2.
#include <iostream>
int main()
{
int* a = new int[5]{10, 10, 10, 10, 10};
for ( int i = 0; i < 5; ++i )
{
std::cout << a[i] << " ";
}
std::cout << std::endl;
}
Output:
10 10 10 10 10
Update, in response to OP's comment
When you use
std::vector<int> v(5, 10);
the constructor of std::vector used is:
vector( size_type count,
const T& value,
const Allocator& alloc = Allocator());
Let's say you have a class
class MyClass
{
public:
MyClass(int ) {}
};
You can construct a std::vector<MyClass> using:
std::vector<MyClass> v(10, MyClass(50));
or
std::vector<MyClass> v(10, 50);
In the second case, the compiler knows how to implicitly construct a temporary MyClass object given the argument 50 alone. But either way, a temporary MyClass object is being passed to the vector, and that is OK because the argument type of that parameter is const MyClass&, which can bind to a temporary object.

Element count of an array in C++

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.

c++ allocate array syntax question

You can write like this:
int test[] = {1,2,3,4};
but what if you want to use a pointer and allocate it with new?
int *test2;
test2 = new int[]{1,2,3,4};
This does not work, what is the syntax or is it possible?
This is one of the short-comings of current standard C++. Initialization is not uniform. Your best hope is uniform initialization in C++0x, but for the mean while you can assign the values after creating the array, e.g.
int *test2;
test2 = new int[4]; // Note that you still have to specify the size in C++0x
test2[0] = 1;
test2[1] = 2;
test2[2] = 3;
test2[3] = 4;
If you compiler supports C++0x
int *test2;
test2 = new int[4] {1,2,3,4}; // Initializer list in C++0x
would work. However you should always use std::vector instead of C style arrays while writing good C++ code.
The first syntax is called aggregate initialization, and you cannot apply it to a dynamically allocated array. When allocating dynamically you must provide the number of elements that you want to initialize inside the square brackets and (optionally) the default value in parenthesis (if you want the array initialised). The default value will be the same (if present) for all elements.
You may want to look into the boost::assign library that may have support for this type of initialization (not sure). Alternatively you can (at the cost of more code) do it yourself for POD types:
int * array = new int[4];
{
int values[] = { 1,2,3,4 };
memcpy( array, values, sizeof(values) );
}
Or for non-pod types:
type * array = new type[4];
{
type values[] = { 1,2,3,4 }; // assuming type(int) constructor
std::copy( values, values+4, array ); // better to use some magic to calculate size
}
At any rate both of those solutions require allocating locally and the copying (bit-size/c++) into the dynamically allocated memory.