I have not been able to find the answer elsewhere, so I guess I just have to ask this one: I am trying to get an alias for a vector (in which int pointers are stored), as below:
void conversion(Engine * ENGINES)
{//The Engine class has a vector of int* as a public data member called SITE
for (int i = 0; i < 3; i++)
{
vector <int*>* current = &(ENGINES[i].SITE);//the problematic line
int j_max = current -> size();
cout << j_max << endl;
for (int j = 0; j < j_max; j++)
{
for (int k = 0; k < 3; k++)
{
if (*current[j][k] == 2)
*current[j][k] = 1;
if (*current[j][k] == -1)
*current[j][k] = 0;
}
}
}
}
The problem is that there seems to be an inversion of the indices for the *current[a][b]. I want to be able to use current as a normal vector, but now the indexing is reversed compared to:
vector <int*> current1 = ENGINES[1].SITE;
so that *current[i][j] = current1[j][i] for some reason. Is there a mistake in my syntax?
I believe your problem is that [] has higher precedence than unary *. So you're getting *(current[j][k]) instead of (*current)[j][k], which is what you want.
However you could eliminate that problem by just taking a reference rather than a pointer:
vector <int*>& current = (ENGINES[i].SITE); and then just remove your extra loading * operators on access to current.
The problem is that [] has greater precedence than * (dereference), so *current[i][j] is interpreted as *(current[i][j]), which is probably not what you want.
Actually, this idiom of aliasing is commonly expressed as a reference, not a pointer:
vector <int*>& current = ENGINES[i].SITE;
and use simply current[i][j].
As I suspected in my comment, use a reference.
vector <int*> ¤t = ENGINES[i].SITE;
Related
Probably a very simple thing, but I am new to C++, Eigen, etc.
I have a MatrixXD with n rows. Each row holds 3 points (x,y,z) and I have a function that takes a vector3d type pointer as an input. I want to iterate over all rows n of the MatrixXd and use pass each row as a vector to my function.
I assume it is a combination of accessing the MatrixXd pointers - maybe with something like this:
int r = mydata.rows();
int c = mydata.cols();
for (int i = 0; i < r; ++i)
{
for (int j = 0; j < c; ++j)
{
myObject.myfunction(&mydata(i,j));
}
}
and using the returned pointers to call my function on each of the rows i.e. for each iteration.
Update 1:
This seems it might work. However, I need to have mydata(i,j) return pointers instead of the data.
Another problem I think I can see: In the current form, I think this is just returning the elements at i,j but I actually need to return a pointer to a Vector3D. Might data.row(i) work for that?
Update 2:
Something like this might be more what I need. Still not working though. I removed the & - which makes sense - and it's working now.
int r = data.rows();
int c = data.cols();
for (int i = 0; i < r; ++i)
{
myObject.myFunction(data.row(i));
}
Can you give me some idea if I am going down the right road, on how to approach this or what other details you would need to help me more?
Solved. The above-posted code works for me.
int r = data.rows();
int c = data.cols();
for (int i = 0; i < r; ++i)
{
myObject.myFunction(data.row(i));
}
I have a List class for char arrays. And I want to push back N arrays from 'a' to 'a..a'.
char* x;
SList list;
for (unsigned int i = 1; i < n+1; i++) {
x = new char[i+1];
for (unsigned int j = 0; j < i; j++) {
x[j] = 'a';
}
x[i] = '\0';
list.push_back(&x);
}
But every time, x has the same address. And in result, my List object contains N pointers to the same address.
Is there a way to push back these arrays in loop with correct memory allocation?
Before asking found this question, but it doesn't provide a cool solution for my problem.
In each iteration of the loop x = new char[i+1]; returns a different address, which is stored in x. So the value of x changes in each iteration, yet, the address of x doesn't.
Did you mean
list.push_back(x);
to add the address of the newly allocated memory? Of course this would require you to change the type of list the a collection of char *.
It must be mentioned that dereferencing &x after x goes out of scope will lead to undefined behaviour, because x doesn't exist anymore. You fill list with dangling pointers.
Finally I'd like to mention that you could avoid the nasty manual memory management and simply use a std::vector<std::string>.
std::vector<std::string> list;
for (unsigned int i = 1; i < n+1; i++) {
std::string newString(i, 'a'); // string with i times 'a'
list.push_back(newString);
}
Ok. I found a pretty straightforward solution:
char** x = new char*[n];
SList sl;
for (unsigned int i = 0; i < n; i++) {
x[i] = new char[i+1];
for (unsigned int j = 0; j < i; j++) {
x[i][j] = 'a';
}
x[i][i] = '\0';
sl.push_back(&x[i]);
}
With having N addresses to store pointers to arrays. I can just add their addresses to my list object
I keep getting errors "subscript requires array or pointer type" when working with an array of pairs. I've looked at all the other threads with similar problems, but have been unable to resolve it.
I dynamically declared an array of pairs which looks like:
pair<T, int> *m_Array;
And set the array size with:
m_Array = new pair<T, int>[c];
Now what I am failing to do is access the first and second of the pair, in an index of the array. I get the error when I try to do things like this.
for (int i = 0; i < m_Size; i++) {
m_Array->first[i] = rhs.m_Array->first[i];
m_Array->second[i] = rhs.m_Array->second[i];
}
It intuitively seems like it should be more like the following code, but my IDE does not like me having m_Array[i]
for (int i = 0; i < m_Size; i++) {
m_Array[i]->first = rhs.m_Array[i]->first;
m_Array[i]->second = rhs.m_Array[i]->second;
}
You're nearly there.
If m_Array is a pointer to some pairs, then m_Array[0] is the first pair; then m_Array[0].first is the "first" member of that first pair.
There is no need for the dereferencing member access operator ->, as the subscription [i] has already dereferenced for you (that is, m_Array[i] means *(m_Array + i)). So you just need the normal member access operator..
So:
for (int i = 0; i < m_Size; i++) {
m_Array[i].first = rhs.m_Array[i].first;
m_Array[i].second = rhs.m_Array[i].second;
}
Or you could skip all this trouble and just write:
for (int i = 0; i < m_Size; i++) {
m_Array[i] = rhs.m_Array[i];
}
Or you could skip that too and change from new and arrays to a nice std::vector, then have it do all the work for you.
I have this function
void shuffle_array(int* array, const int size){
/* given an array of size size, this is going to randomly
* attribute a number from 0 to size-1 to each of the
* array's elements; the numbers don't repeat */
int i, j, r;
bool in_list;
for(i = 0; i < size; i++){
in_list = 0;
r = mt_lrand() % size; // my RNG function
for(j = 0; j < size; j++)
if(array[j] == r){
in_list = 1;
break;
}
if(!in_list)
array[i] = r;
else
i--;
}
}
When I call this function from
int array[FIXED_SIZE];
shuffle_array(array, FIXED_SIZE);
everything goes all right and I can check the shuffling was according to expected, in a reasonable amount of time -- after all, it's not that big of an array (< 1000 elements).
However, when I call the function from
int *array = new int[dynamic_size];
shuffle_array(array, dynamic_size);
[...]
delete array;
the function loops forever for no apparent reason. I have checked it with debugging tools, and I can't say tell where the failure would be (in part due to my algorithm's reliance on random numbers).
The thing is, it doesn't work... I have tried passing the array as int*& array, I have tried using std::vector<int>&, I have tried to use random_shuffle (but the result for the big project didn't please me).
Why does this behavior happen, and what can I do to solve it?
Your issue is that array is uninitialized in your first example. If you are using Visual Studio debug mode, Each entry in array will be set to all 0xCC (for "created"). This is masking your actual problem (see below).
When you use new int[dynamic_size] the array is initialized to zeros. This then causes your actual bug.
Your actual bug is that you are trying to add a new item only when your array doesn't already contain that item and you are looking through the entire array each time, however if your last element of your array is a valid value already (like 0), your loop will never terminate as it always finds 0 in the array and has already used up all of the other numbers.
To fix this, change your algorithm to only look at the values that you have put in to the array (i.e. up to i).
Change
for(j = 0; j < size; j++)
to
for(j = 0; j < i; j++)
I am going to guess that the problem lies with the way the array is initialized and the line:
r = mt_lrand() % size; // my RNG function
If the dynamically allocated array has been initialized to 0 for some reason, your code will always get stack when filling up the last number of the array.
I can think of the following two ways to overcome that:
You make sure that you initialize array with numbers greater than or equal to size.
int *array = new int[dynamic_size];
for ( int i = 0; i < dynnamic_size; ++i )
array[i] = size;
shuffle_array(array, dynamic_size);
You can allows the random numbers to be between 1 and size instead of between 0 and size-1 in the loop. As a second step, you can subtract 1 from each element of the array.
void shuffle_array(int* array, const int size){
int i, j, r;
bool in_list;
for(i = 0; i < size; i++){
in_list = 0;
// Make r to be betwen 1 and size
r = rand() % size + 1;
for(j = 0; j < size; j++)
if(array[j] == r){
in_list = 1;
break;
}
if(!in_list)
{
array[i] = r;
}
else
i--;
}
// Now decrement the elements of array by 1.
for(i = 0; i < size; i++){
--array[i];
// Debugging output
std::cout << "array[" << i << "] = " << array[i] << std::endl;
}
}
You are mixing C code with C++ memory allocation routines of new and delete. Instead stick to pure C and use malloc/free directly.
int *array = malloc(dynamic_size * sizeof(int));
shuffle_array(array, dynamic_size);
[...]
free(array);
On a side note, if you are allocating an array using the new[] operator in C++, use the equivalent delete[] operator to properly free up the memory. Read more here - http://www.cplusplus.com/reference/new/operator%20new[]/
I have a Deck object (deck of cards) which is a double-ended queue implemented as a doubly-linked list. I would like to be able to shuffle the queue at will, but the way I would go about it is beyond me. So instead I've opted to pre-shuffle an array a pointers to the cards and enqueue them after the fact. Problem is, the code I have now doesn't seem to be initializing the pointers at all.
void BuildDeck(Deck* deck) {
Card** cards = new Card*[20];
const size_t MAX_INTEGER_LENGTH = sizeof(int) * 4;
char szPostfix[] = "_Card.bmp";
for(int i = 1; i < 21; i++) {
char path[MAX_INTEGER_LENGTH + sizeof(szPostfix) + 1];
sprintf(path,"%d%s",i, szPostfix);
cards[i-1] = new Card(i,path);
}
ShuffleArray(cards);
for (int i = 0; i < 20; i++) {
deck->PushTop(cards[i]);
}
}
void Swap(Card* a, Card* b) {
Card temp = *a;
*a = *b;
*b = temp;
}
void ShuffleArray(Card** cardArray) {
srand(dbTimer());
for (int i = 0; i < 20; i++)
Swap(cardArray[i],cardArray[rand()%20]);
}
I think where I screwed up is in the card[i] = new Card(...) line, but it somehow looks right to me.
Any suggestions would be appreciated.
DISCLAIMER: I know I should be using the standard library for most of this stuff, but I'm trying to teach myself the hard stuff first. It's just the way I learn.
EDIT: I fixed the index problem. Now I've just gotta figure out why some image aren't drawing now... :/ Thanks for the help!
Your code has many problems
You are looping with 1 <= i <= 20 but for an array of 20 elements indexing goes from 0 <= index <= 19. You need to use cards[i-1] = new Card(i,path);
You are allocating the array of pointers cards but you are not deallocating it (memory leak). Either deallocate it with delete[] cards; once you are done or just use a stack based array with Card *cards[20]; instead of allocating it with new.
The way you compute MAX_INTEGER_LENGTH shows you don't really understand what sizeof does.
This is the reason for which the cards don't get shuffled. You wrote a function that swaps two pointers, but the pointers it is swapping are local variables (parameters) of the function, not the elements of the array. One solution is to pass the parameters as pointer references by declaring swap with void Swap(Card *& a, Card *& b), another solution would be passing pointers to pointers (but this would require a more complex syntax of the implementation because of the double indirection and would also require a change in the way you call the function).
In the first for loop your starting index is 0, while in the second for loop the starting index is 0. That could be the problem.
Your code:
for(int i = 1; i < 21; i++) {
char path[MAX_INTEGER_LENGTH + sizeof(szPostfix) + 1];
sprintf(path,"%d%s",i, szPostfix);
cards[i] = new Card(i,path);
}
Here the loop should start from 0 to 20 as:
for(int i = 1 ; i < 21; i++) //incorrect - original code
for(int i = 0 ; i < 20; i++) //correct - fix
And after the fix, you could use i+1 instead of i in :
sprintf(path,"%d%s",i+1, szPostfix);
cards[i] = new Card(i+1,path);
if that is required.