Does the array key determine array size in C++? - c++

im storing some settings for objects in an array. the id's of objects are used as the key. the id's start from 100000 and go up. if i was to input data for an object with id 100 000, would cpp automatical create 99999 blank key entries starting from 0?

Array size is determined when you create an array.
To access object at index 100 000 you need to have array of at least that size, which answers your question.
If the array is smaller you will access memory at
array begin address + (index*object
size)
which is not a good thing. E.g. the following will print some data but it is a data that are stored at that point in memory and it's outside of your array (not a good thing):
string arr[3];
cout << arr[5] << endl;
Assuming you are talking about standard array like:
string arr[10];
Array's size is specified when you compile it, for example you can't do:
string arr[]; // this will fail to compile, no size specified
But you do:
string arr[] = {"1","2","3"}; // array size is 3
string arr1[3]; // array size is 3
string arr2[3] = {"1"}; // array size is 3
If you want to map extra parameters for object you are better off using std::map like:
class person {};
std::map<person*,int> PersonScore;
This assumes that the additional parameters are not logically part of the object otherwise you would just add them to the object.

Maybe you want somthing along the lines of:
class ArrayPlus100k {
Item underlyingArray[NUM_ELEMENTS];
public:
Item& operator [] (int i) { return underlyingArray[i-100000]; }
// etc.
}

If you truely mean an array, and by key you mean index, then subtracting 100,000 from your index will provide you with a zero based array index. There will be no unused entries.

There may be a better container than a flat array. Choosing the right data structure depends on what you are trying to do. If you are storing objects using a key, you might want to use a std::map<key, value>.
What happens depends entirely on the data structure you choose to use. If you use a map, only the items you insert will take up space in memory. If you use new to allocate an actual array, then you will want to allocate only enough space for for the items you want to store. In that case, adjust your index by subtracting 100,000.

No, it will not create 0-99999, but rather start from 100000 to your array size.
For example, if you declare the following:
int arr[5];
Starting from arr[2], you can store up to arr[7].
I hope you understand...

Related

How are vectors(in C++) having elements of variable size allocated?

I wrote the following code to accept test-cases on a competetive programming website. It uses a vector input of the structure case to store the inputs for given test-cases all at once, and then process them one at a time( I have left out the loops that take the input and calculate the output because they are irrelevant to the question.)
#include<iostream>
#include<vector>
using namespace std;
struct case{
int n, m;
vector<int> jobsDone;
};
int main(){
int testCase;
cin>>testCase;
vector<case> input;
input.reserve(testCase);
//The rest of the code is supposed to be here
return 0;
}
As I was writing this code, I realised that the working of input.reserve(t) in such a case where the element size is variable(since each instance of the structure case also has a vector of variable size) would be difficult. Infact, even if I had not explicitly written the reserve() statement, the vector still would have reserved a minumum number of elemtns.
For this particular situation, I have the following questions regarding the vector input:
Wouldn't random access in O(1) time be impossible in this case, since the beginning position of every element is not known?
How would the vector input manage element access at all when the beginning location of every element cannot be calculated? Will it pad all the entries to the size of the maximum entry?
Should I rather be implementing cases using a vector of pointers pointing to each instance of case? I am thinking about this because if the vector pads each element to a size and wastes space, or it maintains the location to each element, and random access is not constant in time, hence there is no use for a vector anyway.
Every object type has a fixed size. This is what sizeof returns. A vector itself typically holds a pointer to the array of objects, the number of objects for which space has been allocated, and the number of objects actually contained. The size of these three things is independent of the number of elements in the vector.
For example, a vector<int> might contain:
1) An int * holding the address of the data.
2) A size_t holding the number of objects we've allocated space for
3) A size_t holding the number of objects contained in the vector.
This will probably be somewhere around 24 bytes, regardless of how many objects are in the vector. And this is what sizeof(vector<int>) will return.

can we check the size of dynamic array on runtime

I create an array of size int arr[50]; but I will insert value in it during compile time , like my solution will insert 10 values in it after performing some function (different amount of values can come) , Now in second part of my program I have to loop through the array like it should iterate <= total values of array like in int arr[50] my program save 10 values , it should iterate to it only 10 times but how I can get that there is only 10 values in that array.
arr[50]=sum;
for (int ut=0; ut<=arr[100].length();ut++)
Though i know ut<=arr[100].length() is wrong , but its just assumption , that function will work if I solve condition in this way.
Edit:
I know we can use vector , but I am just looking that type of thing using array.
Thanks for response
First of all, the array you show is not a "Dynamic Array". It's created on the stack; it's an automatic variable.
For your particular example, you could do something like this:
int arr[50];
// ... some code
int elem_count = sizeof(arr) / sizeof(arr[0]);
In that case, the sizeof(arr) part will return the total size of the array in bytes, and sizeof(arr[0]) would return the size of a single element in bytes.
However, C-style arrays come with their share of problems. I'm not saying never use them, but keep in mind that, for example, they adjust to pointers when passed as function arguments, and the sizeof solution above will give you an answer other than the one you are looking for, because it would return sizeof(int*).
As for actual dynamically allocated arrays (where all what you have is the pointer to that array), declared as follows:
int *arr = new int[50];
// ... do some stuff
delete [] arr;
then sizeof(arr) will also give you the size of an int* in bytes, which is not the size you are looking for.
So, as the comments suggested, if you are looking for a convenient random access container where you want to conveniently and cheaply keep track of the size, use a std::vector, or even a std::array.
UPDATE
To use a std::array to produce equivalent code to that in your question:
std::array<int, 50> arr;
and then use it like a normal array. Keep in mind that doing something like arr[100] will not do any bounds checking, but at least you can obtain the array's size with arr.size().

Select a random object from an array of objects

I'd like to implement a function that selects a random object from an array of objects and returns it to me. It should be something like (in C++ instead of psuedocode):
getRandomObject(objectList) {
return objectList[int(random(length of objectList))];
}
My current code looks like this, but doesn't seem to work:
//definition of random selector
object getRandomObject(Object* objectList) {
return objectList[int(ofRandom(0, sizeof(objectList)))];
};
//create a pointer for the listOfObjects
object* listOfObjects;
//create an empty object to put the randomly selected object in
object randomObject;
//later in the code, populate the array:
object* listOfObjects[] = {
new Object(),
new Object(),
new Object()
};
//select random object
randomObject = getRandomObject(listOfObjects);
But this seems to return a segmentation fault. A few problems I've noticed:
sizeof() returns the size of the pointer in getRandomObject, not the size of the array. is there a good way to get the size of the array? It might involves not using a float* pointer for the array. Is this a good use case for vectors?
I think that much of the problem lies in how I'm creating my arrays, and not so much in how I'm selecting the random object from them. I'm relatively new to C++ (coming from a Java background), so much of pointers / references / memory management in general is new to me.
thanks!
I see one definite problem and one possible one. The definite problem is that sizeof(objectList) returns the size of the objectList pointer, which will be 4 or 8 on most platforms. It does not return the number of elements in the array, objectList. Either pass in the length of the array or use std::vector or std::array.
The second possible problem relates to ofRandom. Make sure that ofRandom(a,b) returns numbers >= a, but strictly < b. If it returns values <= b, then you'll need to us ofRandom(0, objectVector.size() - 1). Typically, functions like this are written to return values strictly < b, but you should check.
C++ has an array template class that you may want to consider using. Check out the documentation here:
http://www.cplusplus.com/reference/array/array/
This type has a method, size(), that will return the length of the array.
When the sizeof operator is applied to an array, it yields the total
number of bytes in that array, not the size of the pointer represented
by the array identifier.
Quote
So you take the space alocated for your whole array and divide by the memory need just for one element: sizeof(objectList) / sizeof(*objectList).
Mr Fooz noticed issues that cause a segfault.
Other compilation issues are:
listOfObjects is declared with 2 different types: object* and object*[3] while getRandomObject expects a type Object*.
listOfObjects[] contains elements of type object* while getRandomObject reads elements of type Object and returns object.

getting the number of elements in a struct

I have a struct:
struct KeyPair
{
int nNum;
string str;
};
Let's say I initialize my struct:
KeyPair keys[] = {{0, "tester"},
{2, "yadah"},
{0, "tester"}
};
I would be creating several instantiations of the struct with different sizes. So for me to be able to use it in a loop and read it's contents, I have to get the number of elements in a struct. How do I get the number of elements in the struct? In this example I should be getting 3 since I initialized 3 pairs.
If you're trying to calculate the number of elements of the keys array you can simply do sizeof(keys)/sizeof(keys[0]).
The point is that the result of sizeof(keys) is the size in bytes of the keys array in memory. This is not the same as the number of elements of the array, unless the elements are 1 byte long. To get the number of elements you need to divide the number of bytes by the size of the element type which is sizeof(keys[0]), which will return the size of the datatype of key[0].
The important difference here is to understand that sizeof() behaves differently with arrays and datatypes. You can combine the both to achieve what you need.
http://en.wikipedia.org/wiki/Sizeof#Using_sizeof_with_arrays
sizeof(keys)/sizeof(*keys);
If you're trying to count the elements of the array, you can make a macro
#define NUM_OF(x) (sizeof(x)/sizeof(x[0]))
You mean the count of elements in keys ? In such a case you can use int n = sizeof(keys)/sizeof(keys[0]);
In C++ it is generally not possible to do this. I suggest using std::vector.
The other solutions work in your specific case, but must be done at compile time. Arrays you new or malloc will not be able to use those tricks.
If you're trying to calculate the number of elements of the keys array
you can simply do sizeof(keys)/sizeof(keys[0]).
This can not be a general good solution, due to structure padding.

C++ Array of Objects

I have an array in a class that should hold some instances of other objects. The header file looks like this:
class Document {
private:
long arraysize;
long count;
Row* rows;
public:
Document();
~Document();
}
Then in the constructor I initialize the array like this:
this->rows = new Row[arraysize];
But for some reason this just sets rows to an instance of Row rather than an array of rows. How would I initialize an array of Row objects?
Both SharpTooth and Wok's answers are correct.
I would add that if you are already struggling at this level you may be better off using a std::vector instead of a built-in array in this case. The vector will handle growing and shrinking transparently.
This should work. One possible "error" would be an incorrect value for arraySize.
However you should better use a std::vector from the standard library for that purpose.
#include <vector>
class Document {
// ...
std::vector<Row> rows;
// ...
};
and in your constructor:
Document::Document() : rows(arraySize) { // ... }
or
Document::Document() { rows.assign(arraySize, Row()); }
If arraySize contains a reasonable value at that point you actually get an array. I guess you trust your debugger and the debugger only shows the 0th element (that's how debuggers treat pointers), so you think there's only one object behind that pointer.
For i in [0;arraysize[, *(this->rows+i) should be an instance of row.
What precisely makes you think that rows is only one element? Make certain that you arraysize isn't 1. If it is, you'll get an array of 1 element. Mind you, you must still call delete [] with an array of size 1.
Also, why is arraysize different than count? Using that terminology, you should be making an array of count elements and arraysize should be equal to sizeof(Row) * count.
Also, you specifically ask "How would I initialize an array of Row objects?". Do you mean allocate? If so, that's how you would do so. If you mean initialize, the default constructor of Row will be called on each element of the array when the array is allocated.