I have made a node object that populates in an array of 63 x 63. After the first value, it should just access an array attached to the object and put in a value in that array.
The array of objects is defined as:
node ** arr[63][63];
and my function is this:
void addValue(int x, int y, float value)
{
node a = ** arr[x][y];
a.valueList[a.size] = value;
a.size = a.size + 1;
}
The idea is that if there is already a node in the array(when the function is called it can be assumed that there already is one), to add the value to "valueList" on the node that already exists at that spot.
here is how it is called in main:
if(!isValid(arr[xCount][yCount]))
{
node a(0, false, xCount, yCount);
addToArray(&a);
myFile.read((char *) &dataIn, 4);
yCount++;
}
else
{
myFile.read((char *) &dataIn, 4);
addValue(xCount, yCount, dataIn);
yCount++;
}
addValue function is crashing the program, and is not properly adding the value to the array attached to the object. I am guessing it might have something to do with how I am accessing the array "arr[][]".
The whole ** part of the definition of arr, as well as in the assignment to a -- you don't mention these at all in the text of your question. This leads me to suspect that you didn't actually mean to put them there. It sounds like you want a 2D array of nodes, rather than a 2D array of pointers to pointers to nodes. Indeed if you missed that and didn't allocate the nodes and pointers to nodes for the pointers to pointers to nodes to point to, then you'll get a segmentation fault.
BTW, also watch out for a being a copy of the array element, changes to which won't get propagated to arr.
Related
I have a Node class, and when I created an array of Node pointer(Node*) and passed it through the method, I had a different length of the array as the parameter.
Node* hands[4];
Deal(deck,hands,4,"one-at-a-time",13);
void Deal(Node* &deck, Node* hands[], int people, std::string type, int count){
Node*& temp = deck;
for (int i = 0; i < count; ++i) {
for (int j = 0; j < people; ++j) {
append(hands[j], CopyDeck(temp));
temp = temp->after;
}
}
}
When I use Clion debugger to see the value of variables, I found that hands that I create has values of
hands[0] = 0x746365667265700e
hands[1] = NULL
hands[2] = NULL
hands[3] = 0x00007fc44b402430
And when it is passed through the method, in method the hands is
*hands=0x746365667265700e
hands[1]=NULL
hands[2]=NULL
hands[3]=0x00007fc44b402430
hands[4]=0x00007fc44b402570
What does the "*hands" stand for? And why the initial value in hands are not NULL? Actually the minimal example I can have is something like:
class Node{};
void test(Node* list[]){}
int main(int argc, char* argv[]){
Node * temp[4];
test(temp);
}
But it works. And I have already written the same code in other files and works as I thought.
The deck is a simply doubly-linked list of Node. Node has an attribute "after" point to the next Node. My debugger told me before
Node* &temp = deck;
the parameter "hands" already becomes a 5 elements array.
I think I found a possible reason but I can't understand the relationship between. There are two test methods in my main function. The first one is called "SortingTest" and the second one is "DealingTest". When I comment the first test method out, my DealingTest works properly, but after I uncomment it, the DealingTest doesn't work. After SortingTest ends there is no attribute or anything left in the main method. Can anyone explain it to me? Thank you all. Or maybe my clear method is wrong so it not frees the memory correctly?
void DeleteAllCards(Node* root){
Node *current, *next;
current = root;
while (current != nullptr){
next = current->after;
delete current;
current = next;
}
}
The array you created is a C-Style array, which is a fixed size array with 4 elements. In your case, the element type is Node pointer.
C-Arrays do not initialize with default values, unlike many other popular languages. Therefore, the pointer values you are seeing in hands are either a pointer to a Node * or derived type or a garbage memory address with some exceptions to this rule (see below for the edge cases defined by the Standard. For the ones that do say NULL, their memory address is at ox0000...
Update Edit To reflect a comment made by #AlgirdasPreidZius -
For C and C++, there is a standard rule where a standard C-Array shall be populated with default values upon initialization. C++ standard section 6.8.3.2.2 ([basic.start.static]): "If constant initialization is not performed, a variable with static storage duration or thread storage duration is zero-initialized."
As to why your array has those values in them from the function provided, we need more context. A reproducible example is always the best.
Your for loop, judging by the passed in parameters, is an N^2 time complexity loop with 4*4 iterations. The C-Array Node * was also passed in by reference, so when you assign Node *& to deck, the memory address marking the start of the array changes to the location of the deck array. So, it will have the values that the deck C-Array of Node *'s contains, assuming copy is a 1 : 1 copy, deep or shallow
I have declared a basic structure as below.
struct Item
{
MPoint key; //4 element double array x,y,z,w represents a point in space
Item * next = NULL;
};
I have a small array of pointers to these structures
Item * arr[3];
When an item is created, the key is defined by its location which is a unique point in 3D space.
Item hti; //create a new item struct called hti
hti.key = transf.rotatePivot(MSpace::kWorld);
Item * p_hti = &hti; //pointer to the struct
arr[0] = p_hti;
The main problem is that when i watch the arr[0] variable in my debugger, it shows the correct key values. However, as soon as I examine the data as in
double x = arr[0]->key.x;
Instead of getting the correct value for x, i get x = -9.2559631349317831e+61 every time and for all the other values in the key (x,y,z).
I assume that the strange value above represents memory that is uninitialized but it just doesn't make sense to me how the array correctly holds the value up until I try to pull the value back.
Any help would be appreciated!
In your example where you write:
Item hti; // declared on the stack
// ...
Item* p_hti = &hti; // points to item on the stack
arr[0] = p_hti; // points to item on the stack
You are causing this array to reference items that are in the current stack frame and which will be undefined after leaving this stack frame (or which could be corrupted if you perform an operation that corrupts the current stack). Is your dereference of this array happening in the same function? Or does it happen after you return "arr" from the function in which you initialized it? If the latter, that would explain your problem... the memory it references has gone out of scope. To prevent that issue, you should use dynamic memory allocation (with new) in initializing your array (you'll also need to remember to deallocate that after you are done with it with a corresponding delete).
I'm new to C++ and I learned with different tutorials, in one of them I found an example of code:
I have pointed by numbers of lines, that I completely do not understand;
Does this array in array or something like that?
I can understand the second call, but what is the first doing? There is already
"coordinates[blocks[num]]", aren't there? Why need again blocks(i) ?
How do you make this part of the code easier? Did struct with this arrays
don't make easier getting value from arrays?
Thanks in advance!
// Global vars
Struct Rect {
float left;
}
Rectangle *coordinates;
int *blocks;
coordinates = new Rect[25];
blocks = new int[25];
// in method storing values
const int currentBlock = 0; //var in cycle
coordinates[currentBlock].left = column;
blocks[currentBlock] = currentBlock;
//get element method
const Rect& classA::Coords(int num) const
{
return coordinates[blocks[num]]; //(2)
}
//and calling this method like
Coords(blocks[i]); //(3)
Coords(i); //(3)
// (4)
No, not really. Lots of people will think of them as arrays and even describe them as arrays, but they're actually not. coordinates and blocks are both pointers. They just store a single address of a Rect and an int respectively.
However, when you do coordinates = new Rect[25];, for example, you are allocating an array of 25 Rects and setting the pointer coordinates to point at the first element in that array. So, while coordinates itself is a pointer, it's pointing at the first element in an array.
You can index coordinates and blocks like you would an array. For example, coordinates[3] will access the 4th element of the array of Rects you allocated. The reason why this behaves the same as arrays is because it actually is the same. When you have an actual array arr, for example, and you do arr[4], the array first gets converted to a pointer to its first element and then the indexing occurs.
No, this is not an array of arrays. What it is doing is looking up a value in one array (blocks[num]) and using that to index the next array (coordinates[blocks[num]]). So one array is storing indices into the other array.
I'll ignore that this won't compile, but in both cases you are passing an int to the Coords function. The first case looks incorrect, but might not be. It is taking the value at blocks[i], passing that to the function then using that value to index blocks to get another value, then using that other value to index coordinates. In the second case, you are just passing i, which is being used to index blocks to give you a value with which you index coordinates.
That's a broad question that I don't think I can answer without knowing exactly what you want to simplify and without seeing some real valid code.
I'm new to using C++ for complicated programming. I've been sifting through some leftover, uncommented, academic code handed down through my department, and I've stumbled across something I have no real idea how to google for. I don't understand the syntax in referencing an array of structs.
Here is a trimmed version of what I'm struggling with:
typedef struct
{
double x0,y0;
double r;
} circle;
double foo()
{
int N = 3;
double mtt;
circle circles[N];
for (int i = 0; i < N; i++)
{
mtt += mtt_call_func((circles+i), N);
}
return mtt;
}
What does (circles+i) mean in this case?
EDIT: the function should have (circles + i), not (circle + i).
circles+i is equivalent to &circles[i]. That's how pointer arithmetic works in C++.
Why is there a pointer? Well, when you give the name of an array, in a context other than &circles or sizeof circles, a temporary pointer is created that points to the first member of the array; that's what your code works with. Arrays are second-class citizens in C++; they don't behave like objects.
(I'm assuming your circle+i was a typo for circles+i as the others suggested)
circle+i means "take a pointer circle and move it i times by the size of the object pointed to by it". Pointer is involved because the name of the array is a pointer to it's first element.
Apart from this you should initialize an integer counter variable that is used in loop:
for (int i = 0; i < N; i++)
^^^^
{
mtt += mtt_call_func( ( circles + i), N);
^ // typo
}
In C, as in C++, it is legal to treat an array as a pointer. So circles+i adds i times the size of circle to the address of circles.
It might be clearer to write &circles[i]; in this form, it is more obvious that the expression produces a pointer to the ith struct in the array.
Each vector you declare in stack it's actually a pointer to the first index, 0, of the vector. Using i you move from index to index. As result, (circles+i) it's the equivalent of &circles[i].
& means the address of the variable. As in your function call, you send a pointer which stores an address of a variable, therefore & is required in front of circles[i] if you were to change to that, as you need the address of the i index of the vector circles to run your function.
For more about pointers, vectors and structures check this out: http://pw1.netcom.com/~tjensen/ptr/pointers.htm
It should cover you through ground basics.
I have two questions:
1) How can I make an array which points to objects of integers?
int* myName[5]; // is this correct?
2) If I want to return a pointer to an array, which points to objects (like (1)) how can I do this in a method? ie) I want to impliment the method:
int **getStuff() {
// what goes here?
return *(myName); // im pretty sure this is not correct
}
Thanks for the help!
How can I make an array which points
to objects?
int * myName[5]; /* correct */
If I want to return a pointer to an
array, which points to objects (like
(1)) how can I do this in a method?
Technically, you write this function:
int * (* getStuff() )[5] {
return &myName;
}
That returns a pointer to that array. However, you don't want to do that. You wanted to return a pointer to the first element of the array:
int ** getStuff() {
return myName; /* or return &myName[0]; */
}
That way, you can now access items as you want like getStuff()[0] = &someInteger;
Note that your code,
int* myName[5];
declares an array containing 5 values, each of which is a "pointer to int", which is what you asked.
However this being C++, that's all it does. As a Python scripter, that might cause you some surprises.
It does not give any of those 5 pointers sensible values, and it does not create any integers for them to point to.
If you put it in a function body, then it creates the array on the stack. This means that the array will cease to exist when the current scope ends (which, to put it simply, means when you get to the enclosing close-curly, so for example return does it). So in particular, the following code is bad:
int **myFunction() {
int *myArray[5];
return myArray;
} // <-- end of scope, and return takes us out of it
It might compile, but the function returns a pointer to something that no longer exists by the time the caller sees it. This leads to what we call "undefined behaviour".
If you want the array to exist outside the function it's created in, you could create one on the heap each time your function is called, and return a pointer, like this:
int **myFunction() {
int **myArray = new int[5];
return myArray;
}
The function returns a different array each time it's called. When the caller has finished with it, it should destroy the array, like this:
delete[] myArray;
otherwise it will never be freed, and will sit around using up memory forever (or when your program exits on most OSes).
Alternatively, you can use the keyword "static" to create an array with "global storage duration" (meaning that it exists as long as the program is running, but there's only one of it rather than a new one each time). That means the function returns the same array each time it's called. The caller could store some pointers in it, forget about it, call the function again, and see the same pointers still there:
int **myFunction() {
static int *myArray[5];
return myArray;
}
Note how similar this code is to the very bad code from earlier.
Finally, if you just want to create an array of integers, not an array of pointers to integers, you can do this:
int myArray[5] = { 1, 2, 3, 4, 5};
That actually creates 5 integers (meaning, it assigns space which can store the integer values themselves. That's different from the array of pointers, which stores the addresses of space used to store integer values).
It also stores the specified values in that space: myArray[0] is now 1, myArray[1] is 2, etc.
1) Correct - this is an array of 5 pointers to ints
2) You can return a pointer to an array of pointers to ints by returning a pointer to the first element of that array. This has two levels of indirection, so you need two asterisks. You can also return the array normally, since arrays automatically decay into pointers to their first elements.
int **getStuff() {
return myName; // 1
return &myName[0]; // 2
}
int **myName;
int **getStuff() {
int **array = new int*[5];
for (int i = 0; i < 5; i++)
{
int key = i;
array[i] = &key;
}
return array;
}
Steve Jessop, I think you meant:
int **myFunction() {
int **myArray = new int*[5];
return myArray;
}
This returns a heap array pointer (not pointer to its elements), testable and deletable. Nothing leaks.
template <class T>
T* newarray(int len)
{
T *a;
try
{
a = new T[len];
memset(a,0,len*sizeof(T));
return a;
}
catch (...)
{return 0;}
}
.
.
.
void foo()
{
float *f=0;
f=newarray<float>(1000000);
if(!f) return;
//use f
delete [] f;
}