I don't know if I have misinterpreted information or something but I thought using new would allocate dynamic memory that must be forcefully deallocated rather than deallocation at the end of a scope.
1 2 3 4 5 6 7 8 9 10 11
#include <iostream>
int main()
{
bool x = false;
do
{
int *p = newint;
}while(x);
std::cout << p;
}
Why doesn't that work? Isn't *p supposed to be on the heap or am I missing some syntax?
The memory that is allocated on the heap, using new, does indeed not get deallocated.
However, the pointer you created to point at that memory ( p ) is on the stack, and that pointer ceases to exist when it goes out of scope. That pointer only exists inside the while loop in the example code you posted.
The memory you allocated on the heap is still there, still holding the int that was created with newint; you just no longer have a pointer to that memory.
The intent I had was to be able to use a variable outside of a scope, so that it would be usable outside of the dowhile() scope.
I know this is all for demonstration but I can't see the purpose of the below code, unless my comments have misconceptions. I do see the idea that you could reference memory from the heap in order to get data that isn't tied to a local variable within the scope. How could I reference that data without the p pointer?
1 2 3 4 5 6 7 8 9 10 11 12 13
int main()
{
bool x = false;
int *p; //declares pointer to an integer, p.
do
{
p = newint; //allocates memory on heap for an integer, reference this memory with address p.
*p = 10; //value at the heap now equals 10.
}while(x);
std::cout << *p; //outputs value of p.
//How can I output the value at the heap instead of the value at p?
delete p;
}
That doesn't make any sense. An address doesn't have memory space. Variables and objects take up memory space. An address is just a number we use to identify locations in the memory space.
I think I finally understand pointers now at least.
I have an example program which causes some memory leaks sure, but that was besides the point; I just wanted to make sure I understood how all the pointers and things worked.
#include<iostream>
#include"node.h" //node.h is not templated, only holds integers.
int main()
{
int x = 5; //declare, initialize, and define x.
int *p = &x; //declare pointer p, initialize it as address of x/pointer to x.
std::cout << "Value of address " << p << ": " << *p; //outputs the value at p's address, which is x.
std::cout << "\nValue of x: " << x; //outputs value of x.
++p; //p increases in address, probably by 4 given that it is an integer.
std::cout << "\nAddress of p after increment: " << p; //outputs new address of p.
*p = 10; //says the value at the new address of p is 10. The address is not tied to any variable.
std::cout << "\nValue of address " << p << ": " << *p; //outputs new address of p.
std::cout << "\nValue of x: " << x << std::flush; //x has not changed in address or value, but p has, and now refers to an address not linked to a variable.
std::cout << "\n\n Next example program \n\n";
int *p2 = nullptr; //declares pointer with no address or value.
//std::cout << p2; doesn't work because that would mean trying to output an address that doesn't exist. p2 doesn't hold an address yet.
bool isTrue = false;
do
{
p2 = &x; //test this with p2 = &x after defining the value of p2.
//that address doesn't exist so you can't set its value yet.
int x = 10;
*p2 = x;
}while(isTrue);
std::cout << "Address of P2: " << p2; //p2 has an address now.
std::cout << "\nValue at P2: " << *p2 << std::flush;
std::cout << "\n\nNodes example program: \n\n";
std::cout << "See implementation for explanation." << std::endl;
node node1; //declares three nodes with no data and no addresses.
node node2;
node node3;
node1.nextNode = &node2; //sets the address of the first node to node2;
node2.nextNode = &node3; //sets the address of the second node to node3;
node3.nextNode = nullptr;
node *head = &node1; //declares a pointer to a node, head is not a node though, it simply refers to one.
node *tail = &node3; //declares a pointer to a node, tail is not a node though, it simply refers to one.
node3.data = 5; //says that node3's data is 5.
std::cout << node1.nextNode->nextNode->data; //arrow operator points to the nextNode.
std::cout << std::endl << node3.nextNode; //nextNode of node3 refers to a nullptr.
std::cout << std::endl << head->data; //outputs the data of the value associated with the address referred to by head.
std::cout << std::endl << tail->data; //outputs the data of the value associated with the address referred to by tail.
std::cout << std::endl << head->nextNode->nextNode->data; //outputs the data associated with the address of node3.
}
It does have a definite value, the value of nullptr. It is guaranteed to be an invalid address (basically zero, but the technicalities go beyond that). No valid address will compare equal to nullptr. But it is a value!
that address doesn't exist so you can't set its value yet.
You can't assign an address that doesn't exist. The address of x does in fact exist at that point, but it happens to be the x that you defined earlier in your program, not the one defined in the next statement.
Here's a very basic example of a linked list (about as bare-bones as it gets):
#include <iostream>
// It's so easy to template it.
template<typename T>
// Classes are commonly named with an uppercase letter.
struct Node {
T data;
Node* next;
// A constructor is very handy
Node(T d, Node* n) : data(d), next(n) {}
};
int main() {
using IntNode = Node<int>;
IntNode* head = nullptr; // indicates an empty list
// Add integers 0 to 9 to the list, prepending new nodes
for (int i = 0; i < 10; i++)
head = new IntNode(i, head);
// Since we prepended the values, they will print in reverse
for (IntNode* nd = head; nd; nd = nd->next)
std::cout << nd->data << ' ';
std::cout << '\n';
}