Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed last year.
Improve this question
When I try to declare in another way a pointer I try to use the new keyword and give it a try:
#include<iostream>
using std::cin;
using std::cout;
using std::endl;
int main ()
{
int *p = new int;
*p = 5;
cout << *p << endl;
return 0;
}
but when I try to declare the same pointer but without the new keyword it gives me an error like the code below:
#include<iostream>
using std::cin;
using std::cout;
using std::endl;
int main ()
{
int *p;
*p = 5;
cout << *p << endl;
return 0;
}
So what is the reason for that error and what is the difference between the two ways?
You should know the differences.
int *p;
Here, p is just a variable on the stack. It hasn't been initialized so it does not point to a specific location on the memory. Thus when you dereference it and assign a value to the underlying location you are invoking some undefined behavior. In other words, you haven't yet allocated any space on the heap to store an int. So here:
*p = 5;
you are probably assigning the value 5 to a location that does not belong to your program.
Now here:
int *p = new int;
*p = 5;
this is fine. The new operator will reserve 4 bytes on the heap memory and return its address and that address gets stored in the p and now p contains an actual and legal address of a block of memory capable of storing an int. So it is safe to dereference p and assign a value to the underlying location.
Important note: You should almost never deal with new/delete or new[]/delete[] operators and raw pointers. Instead, you should use smart pointers and stick to RAII as much as possible.
Therefore, the correct way of doing the above would be like this:
#include<iostream>
#include<memory>
using std::cin;
using std::cout;
using std::endl;
int main ()
{
std::unique_ptr<int> p { std::make_unique<int>( 5 ) };
cout << *p << endl;
return 0;
}
However, using any type of pointers is wasteful in this case since you can also store small types on the stack:
int num { 5 };
This is the preferred way of storing values unless you are desperate to use dynamic memory allocations (for some reason, like maybe you want an object to have dynamic storage duration, or maybe the object is large and won't fit on the stack).
new int occupies a new memory space on the heap, and p points to that memory space. But on the second example, you didn't specify where p points to (so p can point to anywhere, but you try to assign the memory address p points, so it cause undefined behaviour.
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 months ago.
Improve this question
As the title suggests,
int [] a = new int[size];
constantly throws me an error.
I am not yet familiar with C++ so please help me tweak the code above to as closely similar to the syntax above (above was a given pseudo(?) code in a class) so I can create an array.
Thank you.
#include <iostream>
using namespace std;
// Test program
int main( )
{
int [] a = new int[10];
cout << a[0];
return 0;
}
Tried running the above code and it failed to compile.
new is for dynamic allocation (of an array on the heap in this case), and returns a pointer to the new array.
[] in the declaration are for declaring it to be a stack array (and the brackets belong the right side of the variable name).
So the two legal approaches your code is mixing would simplify to either:
int a[10]; // Declares a stack array of size 10
or:
int *a = new int[10]; // Dynamically allocates a heap array of size 10 and stores the pointer to it in `a`
The former is the better solution here (there's no benefit to a heap allocation for such a small array that is only used within the scope of this function, and it would require explicit delete[] a; later to properly clean it up).
That said, neither version initializes the values, so the contents of a[0] are uninitialized, and reading from them will get random garbage. Both versions can be changed to initialize the data with zeroes though, e.g.:
int a[10] = {0}; // Declares a stack array of size 10 and initializes to zero
or:
int *a = new int[10](); // Dynamically allocates a heap array of size 10 and stores the pointer to it in `a`, initializing to zero
Final note: Using raw new is generally frowned upon in modern C++. If you needed heap-allocated contiguous data storage, you're probably better off using a std::vector.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
I have 3 questions:
Q1. When we create the object using the new operator, following is the syntax:
pointer_variable = new data-type //To create an object
pointer_variable = new data-type(value); //To create an object with value
pointer_variable = new data-type[size]; //To create an array
Why always there is a pointer_variable on L.H.S?
Q2. What is the difference between declaring and assigning pointers with and without the new operator?
Consider the following code snippet and output to understand the question:
int a = 10, b=20;
int *p;
p = &a;
int *q = new int;
q = &b;
cout<<"P is: "<<p<<" : "<<*p<<endl<<"Q is: "<<q<<" : "<<*q<<endl;
Output of the above code:
P is: 0x61ff04 : 10
Q is: 0x61ff00 : 20
Q3. When we say, with a new operator we can dynamically allocate memory to the array at run time when we don't know the size of the array at compile time. We can do this without new operator as given below:
cout<<"Enter the size of an array"<<endl;
int n;
cin>>n;
int arr[n];
for(int i=0;i<n;i++)
{
cin>>arr[i];
}
for(int i=0;i<n;i++)
{
cout<<arr[i];
}
Then what is exactly the need to use the new operator for arrays?
Why always there is a pointer_variable on L.H.S?
Because new-expression results in a pointer.
What is the difference between declaring and assigning pointers with and without the new operator?
new-expression (not operator new) constructs a new object (and, optionally, allocates memory for it).
We can do this without new operator as given below
In fact, we cannot, according to the C++ Standard. Some compilers just allow this construct as a non-standard language extension.
Every good C++ book for beginners will explain these in more details.
in C++, a typical new expression allocates memory on the heap, and returns a pointer to that memory.
Re Q1: you can save the resulting pointer to a local variable for immediate use: pointer_variable = new int. But you don't have to do that: you could instead use it as an argument to a function: use_pointer(new int).
Re Q2: your code allocates an int on the heap, stores its pointer in local variable q, and immediately overwrites it with the address of local variable b. So what you have done here is write a small memory leak.
Re Q3: variable-sized array is a nonstandard extension to C++, so it will not necessarily work in another compiler. However, when it does work it is just another automatic variable: it will be automatically de-allocated for re-use when you leave the local scope. This is different from new allocations, which last until they are explicitly delete-ed.
This question already has answers here:
Can a local variable's memory be accessed outside its scope?
(20 answers)
Closed 8 years ago.
I guess this is a very basic question, but even after looking around on the internet for a while I can't seem to find a proper answer to this question.
I will refer to this tutorial on stack/heap:http://gribblelab.org/CBootcamp/7_Memory_Stack_vs_Heap.html
Let's say I write the following code:
void testVoid() {
int testVariable = 5;
}
If I'm not wrong, this function should create a variable located on the stack. As the functions exits, the allocated memory on the stack is deleted - so my variable should also have been deleted by then.
I have learned that pointers in c++ point to the memory location of a variable.
So if the variable pointed to by a pointer is located on the stack, and the stack then is cleared, I would expect not to be able to access original value through the pointer anymore, since the memory location pointed to is is cleared. However, I tested this:
int* pointer;
void testVoid() {
int num = 3;
pointer = # // Here I get the memory location of my num-variable
cout << pointer << " : " << *pointer << endl; // I would get the same result if i printed &num
}
int main(int args, char** argv) {
pointer = new int;
testVoid();
cout << pointer << " : " << *pointer << endl; // I can still access the memory of my num-variable
while (true) {}
return 0;
}
After exiting the testVoid()-function, where the variable is created, I can still get the value of the variable using my pointer. So obviously I have misunderstood something regarding how pointers work in c++. Printing &pointer and &num gives me the same memory location, even after testVoid() has finished. What is the reason for this? If the memory pointed to by the pointer were moved to the heap, shouldn't cout<<&num and cout<
And here's the output:
0024F904 : 3
0024F904 : 3
Just because the value goes out of scope does not mean the memory for the value has been overwritten. You just can't rely on it being stable at that point.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
When trying to reduce memory use as much as possible, I have seen some programs use additional local scopes. Is this the best way to reduce footprint? Will the variables be removed from the stack when the brackets close? Would it be better to explicitly delete the objects, or is this equally good? Or would the compiler simply remove extraneous brackets?
void foo()
{
{
int a = 4;
BigObject obj1;
obj1.operations(a);
}
{
double b = 9;
BigObject obj2;
obj2.operations(b);
}
}
Yes, they introduce new scopes. Objects with automatic storage duration, i.e. objects on the stack ("local variables"), will go out of scope at the end of this scope.
You are guaranteed that destructors are called, but you are not guaranteed that the object is actually removed from the stack (since stack is an implementation detail -- the standard only talks about automatic storage duration).
However, there is rarely a performance reason for doing so. Instead, it can be useful when using the RAII pattern.
Note, however, that this only applies to local variables. Dynamically allocated memory, i.e. objects on the heap (that you allocate with new), will not be released until you explicitly delete them.
Dynamically allocated memory will have to be pointed to by pointers. C++ clearly separates the concepts of pointer to BigObject and BigObject. In other words, your program is ill-formed. You should write:
BigObject* obj1 = new BigObject();
// ^-- Important!
You can not delete variables with automatic storage, so that part of your question does not make sense.
Not that instead of using new, you should generally prefer using std::unique_ptr instead:
std::unique_ptr<BigObject> obj1 = make_unique<BigObject>();
The memory allocated for your BigObject will be automatically released when obj1 goes out of scope -- this is the RAII pattern.
I have pondered this in the past, but the reality is it does not actually save space according to my nasty experiment. The locals appear to still stock consecutively on the stack:
int _tmain(int argc, _TCHAR* argv[])
{
int* nasty = NULL;
{
int value = 1;
std::cout << &value << std::endl;
}
{
int value2 = 2;
std::cout << &value2 << std::endl;
}
{
int value3 = 3;
std::cout << &value3 << std::endl;
nasty = &value3;
}
std::cout << nasty[0] << ", " << nasty[3] << ", " << nasty[6] << std::endl;
return 0;
}
Output:
001FFC38
001FFC2C
001FFC20
3, 2, 1
what is the difference between the following block of code :
#include<iostream>
using namespace std;
int main()
{
int *p;
float *q;
cout<<p<<"\n"<<q;
}
and this code :
#include<iostream>
using namespace std;
int main()
{
int *p;
float *q;
p = new int;
q = new float;
cout<<p<<"\n"<<q;
}
In both the cases the pointers are allocated some memory right?
Then why should i use the new operator?
No, int *p and float *p declare pointers, but they are not initialised, so they each point to a random address in memory. In particular, they do not point to memory space allocated to your program.
The second piece of code correctly allocates memory and stores the address of that memory in the two pointers. However, note that your code never de-allocates the memory, so you have a memory leak. You'd have to use delete p and delete q at the end of the program to avoid this.
To answer the question in your title a bit more directly: no, you do not have to use the new operator very often in C++; in fact, in well written code you usually use it quite rarely.
In this case, rather than using pointers at all, you would typically want to just define the int and float using the auto storage class, without defining any pointers or using new at all. While you're at it, most code shouldn't have using namespace std; in it either. Fixing those, you could end up with something like this:
#include<iostream>
int main()
{
int p = 1;
float q = 2.0f;
std::cout<<p<<"\n"<<q;
}
If your code has new and/or T *xxx very often (where T is some type and xxx is some identifier) chances are pretty good that it's not really a question of whether you're doing something wrong, only of how many things and how badly wrong.
In the first block of code, memory is allocated for the pointers themselves, but no memory is allocated which they can point to and validly use. The address that is printed out is not safe for your program to use.
The "pointer" variable does already being allocated in main() stack, 4 bytes in 32-bit or 8 bytes in 64-bit machines. The memory storage for int and float, which are pointed by p and q respectively, are not allocated yet in the first case. Your cout just prints out the memory address of p & q, not the value where p or q points to.