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));
Related
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.
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 am working on a C++ program that has a series of class variables that contain vectors on some or all of the member variables. My question is three-fold:
Is it straight-forward to use constructors to initialize vector variables that are part of a class (see sample class definition below)? Could someone post an example constructor for the class below (or for at least the single and two-dimension vector variables)?
Is there a problem with simply initializing the variables myself in my code (i.e., iterating through each element of the vectors using loops to assign an initial value)?
Along the same lines, if the variables need to be initialized to different values in different contexts (e.g., zero in one instance, some number in another instance), is there a way to handle that through constructors?
Sample class definition:
class CreditBasedPoolLevel {
public:
int NumofLoans;
int NumofPaths;
int NumofPeriods;
double TotalPoolBal;
vector<int> NumofModeled;
vector<double> ForbearanceAmt;
vector<double> TotalAmtModeled;
vector<vector<int>> DefCountPoolVector;
vector<vector<double>> TermDefBalPoolVector;
vector<vector<double>> BalloonDefBalPoolVector;
vector<vector<double>> TermDefBalPoolVectorCum;
vector<vector<double>> TermSeverityAmt;
vector<vector<double>> TermELAmtPoolVector;
vector<vector<double>> BalloonELAmtPoolVector;
vector<vector<double>> TermELAmtPoolVectorCum;
};
In C++, initializing a variable calls its constructor. In a vector's case, this means it creates an instance of a vector with whatever the initial capacity is (10 I believe), with no values. At this point, you need to use push_back in order to fill the vector - even though it has a capacity, it will cause undefined behavior if you try to access unfilled areas directly (such as with NumofModeled[0]). You can also initialize it with some amount of space by using vector NumofModeled(x) (x being the number of spaces), but generally because vectors have dynamic size, it's easier to use push_back unless there is some reason you need to enter your data out of order.
Relates to the capacity part of one, if you try to access unfilled space in a vector you will get undefined behavior. It's pretty standard practice to fill a vector with a loop though, such as:
vector<int> v;
int in = 0;
while (cin)
{
cin >> in;
v.push_back(in);
}
Yes, but remember that like functions, constructors only differentiate by the type of input parameters. So, for example, you could have CreditBasedPoolLevel(int level) and CreditBasedPoolLevel(vector<int> levels), but not another with the definition CreditBasedPoolLevel(int otherint), because it would conflict with the first. If you want to be able to take different contextual input of the same type, you can use another variable to define the constructor type, such as CreditBasedPoolLevel(int input, string type) and use a switch block to define the initialization logic based on the type.
As for question number three, simply add a constructor with an argument that is the value you want to initialize the vectors with.
And if you just want the vectors to be default constructed, then there's nothing that needs to be done.
Constructor may look something like this:
CreditBasedPoolLevel::CreditBasedPoolLevel()
{
const int numDefCountPools = 13;
const int numDefCountPoolEntries = 25;
for(int i = 0; i < numDefCountPools; i++)
{
vector<int> v;
for(int j = 0; j < numDefCountPoolEntries; j++)
{
v.push_back(j + i * 5); // Don't know what value you ACTUALLY want to fill here
}
DefCountPoolVector.push_back(v);
}
}
Note that this is ONE solution, it really depends on what values you want, how you went them organized, etc, what is the "right" solution for your case.
let's say I have a class, A
Class A {
int x[100];
vector<int> y;
Fill(x);
Fill(y.begin());
B(x);
B(y.begin());
}
Class Fill (pointer) {
*pointer = 0;
++pointer;
*pointer = 1;
++pointer
}
Class B(container) {
//how do I clear/empty the array and the vector passed by class A given only the pointers to them?
//I must clear an array and a vector in THIS class.
//I DO NOT want to fill them with 0s.
//x and y.begin are POINTERS to the first element of the container, not containers
}
dsfsdakfgnsdfgsf
dg
sdf
gsdf
ghsdf
g
sdfg
ersg
s
Thank you in advance.
For vector:
some_a_pointer->y.resize(0);
You can't do it with just an iterator (y.begin()).
An array's size can never change, so the best you can do is fill it with 0.
std::vector has a method called clear that will clear all the elements.
So my_vector.clear(); will clear everything. However you can't really do the same for arrays. It's just not possible. At best you can fill them with zeroes or go the wrong way and dynamically allocate the array and then delete it. I would rather not deal with memory issues though so I'd just fill them with zero.
C++11 has a class called std::array<T,N> for static arrays of a compile time size and it has a method called fill that would make filling everything to zero easy (a la looping). You can call it with my_array.fill(0);.
I've made a simple program that counts matrices, here's the code:
#include <iostream>
#include <math.h>
using namespace std;
int main()
{
int result[3] = {0,0,0};
int matrixc[3][6] = {
{0,0,0,0,0,1},
{0,0,0,1,1,1},
{1,0,1,0,0,1}
};
for(int x=0;x <3;x++)
{
for(int y=0;y < 6;y++)
{
result[x] += (matrixc[x][y] * pow(2,6-y));
}
cout << result[x] << endl;
}
}
The output is what I wanted, it is: 2,14,and 82.
But, when I delete the initialization in the integer array of result:
#include <iostream>
#include <math.h>
using namespace std;
int main()
{
int result[3]; //deleted initialization
int matrixc[3][6] = {
{0,0,0,0,0,1},
{0,0,0,1,1,1},
{1,0,1,0,0,1}
};
for(int x=0;x <3;x++)
{
for(int y=0;y < 6;y++)
{
result[x] += (matrixc[x][y] * pow(2,6-y));
}
cout << result[x] << endl;
}
}
I got odd outputs: 1335484418,32618, and 65617.
Would you like to explain me why would the output be different between an array with and without an initialization?
Actually, I don't want to initialize all result array, because I have a huge data of matrices.
Is it possible if I use std::vector without initializing all of the result array?
Would you like to explain me why would the output be different between an array with and without an initialization?
Without initialisation, automatic variables aren't initialised. They will have an indeterminate value, depending on what happened to be in the memory they occupy.
Actually, I don't want to initialize all "result" array, because I have a huge data of matrices.
You can zero-initialise the whole array, even if it's huge, like this:
int result[huge] = {};
although, if it is huge, then it shouldn't be an automatic variable. These are typically kept on the stack, which is typically not huge and liable to overflow if you put too much stuff on it.
Is it possible if I use std::vector without initializing all of the "result" array?
Yes, a vector will zero-initialise its elements by default.
Without the initialization, the result array contains undetermined values, i.e. values that could be anything that fits into an int.
As I mentioned in my comment if you do not initialize result it will have undetermined values. Later on your are then adding a value to an unknown value which will still be an unknown value. In this situation you need to initialize your data, can zero initialize like so:
int result[3] = {} ;
Would you like to explain me why would the output be different between an array with and without an initialization?
Seriously? If you don't initialize the array elements they are not initialized!
That means they contains junk data, so when you do result[x] += xxx; you are adding to junk, so you get more junk.
Actually, I don't want to initialize all "result" array, because I have a huge data of matrices.
Then you shouldn't rely on their initial value being zero.
You can do this:
int result[3] = { }; // initialize all elements to zero
Is it possible if I use std::vector without initializing all of the "result" array?
std::vector always initializes its members.
When you delete the initialization of the result array, those locations are initially set to unspecified, arbitrary values. You then add to this arbitrary value within the for loop, and end up those unexpected results. The results may be completely different the next time you run your program.
Also, since result[x] += ... reads from an uninitialized variable, deleting the initialization results in your code having undefined behavior.
If you switch over to using a vector you can zero initialize it as
std::vector<int> result(count); // zero initialized with `count` elements
or
std::vector<int> result; // contains zero elements
result.resize(count); // now it contains `count` elements, all set to 0