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.
Related
Does using a new then setting to null cause memory leaks?
Ive tried the following code but have no idea if it causes any leak or not
#include <iostream>
using namespace std;
int main()
{
int* x = new int;
int y = 1;
x = &y;
x = nullptr; // has the memory allocated to x gone now?
x =&y; // did i recover what was lost?
delete x;
return 0;
}
// the cout<<*x gives 1 as expected
Yes, this is a leak. However, the leak does not occur when you assigned nullptr to x, but rather in the line before it:
x = &y;
x now points to the address of y, and no other references to the memory you allocated with new int exist. Without any references to that memory, there's no way to deallocate it.
The pointed-to-object is lost when you assign to the only pointer that holds it. As stated above, x = &y already loses your new int. Nothing you do afterwards can bring it back. This means that the delete invokes undefined behaviour and might crash your program.
However, there is a mechanism in C++ that avoids such memory leaks: Smart Pointers.
In C++ smart pointers come in two main varieties ::std::unique_ptr<T> and ::std::shared_ptr<T>. They have the job of holding on to an object in dynamic memory and make sure to delete it when it becomes unowned:
::std::unique_ptr<int> x = ::std::make_unique<int>(0);
x = nullptr; // automatically deletes the previously allocated int
This is slightly more expensive than raw pointers but it is less prone to memory leaks. Smart pointers live in the <memory> header.
This question already has an answer here:
C++ Struct Pointer Segfault
(1 answer)
Closed 9 years ago.
I'm new to C++ and pointers and wrote a simple cpp below. I keep on getting a seg fault, but I'm not sure why.
int main() {
int *x = 0;
*x = 8;
return 0;
}
Your integer pointer is null. See this line:
int *x =0
On that line you're setting the memory address of your integer pointer to zero (i.e. nullptr). What I expect you wanted to do is set the value to zero, in which case you'd need to do this:
int main() {
int *x = new int(0);
*x = 8;
return 0;
}
You've declared a pointer to an integer and set it to 0. You haven't actually allocated an integer anywhere. When you assign 8 to the dereferenced pointer, you're trying to write to the memory at location 0. All modern operating systems read and write product the memory at address 0 and anywhere near it to prevent this kind of 'null pointer error'.
Think of memory on a computer as a sheet of graph paper. Each square on the paper has an address, which is the number of squares that came before it. Pointers are for storing these addresses. An int is an actual value, like '5 apples' or '12 downvoting asshats'. These are the values that are stored by writing a number inside one of the rectangles.
However, the OS that manages the system knows that one of the most common kinds of errors people make is forgetting to set up a pointer properly and attempting to write numbers at the very start of the graph paper, so it's designed the graph paper to give you an electric shock if you try to write a number in any of the first few boxes. This is your segmentation fault.
To fix the issue you can either declare an integer on the stack
int i;
int * x = &i;
Declaring something on the stack means the memory will automatically be freed when it leaves scope, i.e. the end of the function.
On the other hand you can allocate a pointer on the heap
int * x = new int;
this means that you're personally responsible for making sure that you free the memory at some later point.
delete x;
Otherwise you're creating a memory leak.
When you define int *x = 0, what you're telling the compiler is "create a integer pointer, x, and set where it points to to 0 (NULL)". What you need to do instead is dynamically create a new pointer. This can be achieved by doing int *x = new int; Then you can change its value. After using it, you should delete it using delete x; to free up its memory.
int *x = 0;
You made an int pointer called x which points to the memory at location 0.
*x = 8;
You tried to write the value 8 into the memory at location 0, which was stored in x. Since this memory is not owned by you, the OS terminated you.
Let's break this down a bit:
int *x = 0
this line creates a pointer called x and points it to NULL (or nowhere)
*x = 8
There is an immediate issue here as soon as you "dereference" x, meaning asking for the spaces associated what x points to.
Since you pointed x at NULL you're asking for the int located at NULL. This is illegal as NULL is an invalid memory space causing a seg-fault.
I'm having trouble understanding arrays of pointers to structures. I created this simple example to try and understand them better. Although it compiles, I keep getting "BAD ACCESS" crashes (nonsense pointers) at the point shown below. Can anyone explain why this is wrong?
#include <iostream>
using namespace std;
struct complex_num {
double real_part;
double imag_part;
};
void init_complex(complex_num *element) {
element->real_part = -1.0; // <--- EXECUTION STOPS HERE.
element->imag_part = 1.0;
}
int main(int argc, char *argv[]) {
int n = 5;
complex_num *array[n]; // Allocates for an array of n pointers to
// the complex_num structure, correct?
for (int i = 0; i < n; i++) {
init_complex(array[i]);
}
return 0;
}
I know there are better ways to do this. I know this is very C in style. Please don't suggest a different data structure. I'm curious specifically about arrays of pointers to structures. Thanks!
You did not allocate memory for your complex_num objects, only for an array with pointers to it. So when you call init_complex, it operates on a pointer to an invalid location.
Try this:
for (int i = 0; i < n; i++) {
array[i] = new complex_num();
init_complex(array[i]);
}
Your statement complex_num *array[n] creates an array of n pointers to complex_num. Meaning, the array can hold n pointers to complex_num; but the pointers themselves are still uninitialized. They point to random locations - every uninitialized primitive (to which pointers belong as well) in C++ will usually simply contain whatever value was in the memory location before the allocation. This will almost certainly lead to unexpected results, as there is no way (or at least no reasonably easy way) of telling where an uninitialized pointer points to.
So you'd have to make each pointer in the array point to some properly set up memory location containing complex_num; only after that you should access (read or write) the values in the complex_num where the pointer points to. To make it e.g. point to a dynamically allocated, new complex_num object, use the above code (notice the new keyword which does the dynamic allocation).
Side note: "Raw" pointers, pointing to dynamically allocated objects, like shown above, are tricky to handle (you should not forget to call delete after you are finished, otherwise you will leak memory), therefore the recommended practice is usually to use smart pointers (like std::shared_ptr, introduced with C++11).
yes, there is no memory allocated to the pointers you have declared. It doesn't point to any valid structure object
I would like to ask a question concerning dynamic memory allocation in C++.
I understand that the nature of the problem I am about to propose is easy to resolve using simple C++ techniques, but for this particular exercise I have to use a more C-like approach.
Let me set an example:
I have the following structs:
typedef struct A{
B *b;
int a;
}
typedef struct B{
C *c;
int x;
}
typedef struct C{
int y;
}
And let's assume this main:
int main(){
A test;
test.a = 1;
test.b = (B*)calloc(2,sizeof(B));
test.b[0].c = (C*)calloc(2,sizeof(C));
test.b[0].x = 2;
test.b[0].c[0].y = 3;
test.b[0].c[1].y = 4;
test.b[1].c = (C*)calloc(2,sizeof(C));
test.b[1].x = 5;
test.b[1].c[0].y = 6;
test.b[1].c[1].y = 7;
}
So my question is as follows:
What happens?
Is there a possibility the memory blocks allocated for test.b[i].c to overlap with the memory blocks that have been previously allocated for test.b?
If that is possible to happen how can I prevent it from happening?
If it is not possible can you explain exactly how calloc() allocates memory? I would really appreciate a numeric example.
Is there a possibility the memory blocks allocated for test.b[i].c to overlap with the memory blocks that have been previously allocated for test.b?
No.
If that is possible to happen how can I prevent it from happening?
It can't happen, so don't worry.
If it is not possible can you explain exactly how calloc() allocates memory?
Every time you call calloc, it gives you back a pointer to a block of zero-initialized memory large enough to hold the requested number of objects, or NULL if it fails. As long as you don't get NULL back, you have nothing else to worry about.
I'm not sure what you mean by "numeric example".
I've been reading through some books, and when it comes to Class/Functions using Pointers/Dynamic Memory (or heap or w/e they call it) I start to get confused.
Does anyone have a simple....like easy example they can show, because the books im using are using overly complex examples (large classes or multiple functions) and it makes it hard to follow. Pointers have always been my weak point anyways but I understand BASIC pointers, just classes/functions using them is a little bit confusing.
Also.....when would you use them is another question.
Stack allocation:
char buffer[1000];
Here the 1000 must be a constant. Memory is automatically freed when buffer goes out of scope.
Heap Allocation:
int bufsz = 1000;
char* buffer = new char[bufsz];
//...
delete [] buffer;
Here bufsz can be a variable. Memory must be freed explicitly.
When to use heap:
You don't know how much space you will need at compile time.
You want the memory/object to persist beyond the current scope.
You need a large chunk of memory (stack space is more limited than heap space)
Your computer's RAM is a big pile of bytes ordered one after another, and each one of those bytes can be accesed independently by it's address: an integer number startig from zero, upwards. A pointer is just a variable to hold that address of a single place in memory.
Since the RAM is a big chunk of bytes, the CPU ussually divides that big pile of bytes on several chunks. The most important ones are:
Code
Heap
Stack
The Code chunk is where the Assembly code lies. The Heap is a big pool of bytes used to allocate:
Global variables
Dynamic data, via the new operation on C++, or malloc() on C.
The stack is the chunk of memory that gets used to store:
Local variables
Function parameters
Return values (return statement on C/C++).
The main difference between the Stack and Heap is the way it is used. While the Heap is a big pool of bytes, the Stack "grows" like a stack of dishes: you can't remove the dish on the bottom unless there are no more dishes on it's top.
That's how recursion is implemented: every time you call a function recursively, memory grows on the stack, allocating parameters, local variables and storing return values of the returning functions, one on top of the others just like the stack of dishes.
Data living on the Stack have different "Life Span" than the data living on the Heap. Once a function exits, the data on the local variables get lost.
But if you allocate data on the Heap, that data won't get lost util you explicitly free that data with the delete or free() operations.
A pointer is basically a variable that contains the memory address of another variable (or in other cases to a function, but lets focus on the first).
That means that if I declare int[] x = {5,32,82,45,-7,0,123,8}; that variable will be allocated to memory at a certain address, lets say it got allocated on address 0x00000100 through 0x0000011F however we could have a variable which indicates a certain memory address and we can use that to access it.
So, our array looks like this
Address Contents
0x00000100 1
0x00000104 32
0x00000108 82
0x0000010B 45
0x00000110 -7
0x00000114 0
0x00000118 123
0x0000011B 8
If, for example, we were to create a pointer to the start of the array we could do this: int* p = &x; imagine this pointer variable got created a memory address 0x00000120 that way the memory at that address would contain the memory location for the start of array x.
Address Contents
0x00000120 0x00000100
You could then access the contents at that address through your pointer by dereferencing the pointer so that int y = *p would result in y = 1. We can also move the pointer, if we were to do p += 3; the pointer would be moved 3 addresses forward (note, however, that it moves 3 times the size of the type of object it is pointing to, here I am making examples with a 32 bit system in which an int is 32 bits or 4 bytes long, therefore the address would move by 4 bytes for each increment or 12 bytes in total so the pointer would end up pointing to 0x0000010B), if we were to dereference p again by doing y = *p; then we'd end up having y = 45. This is just the beginning, you can do a lot of things with pointers.
One of the other major uses is to pass a pointer as a parameter to a function so that it can do operations on certain values in memory without having to copy all of them over or make changes that will persist outside of the function's scope.
Warning: Don't do this. This is why we have vectors.
If you wanted to create an array of data, and return if from a function, how would you do it?
Obviously, this does not work:
int [10] makeArray(int val)
{
int arr[10];
for(int i=0; i<10; ++i)
arr[i] = val;
return arr;
}
You cannot return an array from a function. We can use pointers to refer to the first element of an array, like this:
int * makeArray(int val)
{
int arr[10];
for(int i=0; i<10; ++i)
arr[i] = val;
return &(arr[0]); // Return the address of the first element.
// Not strictly necessary, but I don't want to confuse.
}
This, however, also fails. arr is a local variable, it goes on the stack. When the function returns, the data is no longer valid, and now you have a pointer pointing to invalid data.
What we need to do is declare an array that will survive even after the function exits. For that, we use keyword new which creates that array, and returns the address to us, which needs to be stored in a pointer.
int * makeArray(int val)
{
int * arr = new int[10];
for(int i=0; i<10; ++i)
arr[i] = val;
return arr;
}
Then you can call that function and use that array like this:
int * a = makeArray(7);
for(int i=0; i<10; ++i)
std::cout << a[i] << std::endl;
delete [] a; // never forget this. Obviously you wouldn't do it right
// away like this, but you need to do it sometime.
Using pointers with new also gives you the advantage that you can determine the size of the array at runtime, something you can't do with local static arrays(though you can in C):
int * makeArray(int size, int val)
{
int * arr = new int[size];
for(int i=0; i<size; ++i)
arr[i] = val;
return arr;
}
That used to be one of the primary purposes for pointers. But like I said at the top, we don't do that anymore. We use vector.
One of the last vestiges of pointers is not for dynamic arrays. The only time I ever use them, is in classes where I want one object to have access to another object, without giving it ownership of that object. So, Object A needs to know about Object B, but even when Object A is gone, that doesn't affect Object B. You can also use references for this, but not if you need to give Object A the option to change which object it has access to.
(not tested, just writing down. and keeping things intentionally primitive, as requested.)
int* oneInt = new int; // allocate
*oneInt = 10; // use: assign a value
cout << *oneInt << endl; // use: retrieve (and print) the value
delete oneInt; // free the memory
now an array of ints:
int* tenInts = new int[10]; // allocate (consecutive) memory for 10 ints
tenInts[0] = 4353; // use: assign a value to the first entry in the array.
tenInts[1] = 5756; // ditto for second entry
//... do more stuff with the ints
delete [] tenInts; // free the memory
now with classes/objects:
MyClass* object = new MyClass(); // allocate memory and call class constructor
object->memberFunction("test"); // call a member function of the object
delete object; // free the object, calling the destructor
Is that what you wanted? I hope it helps.
I think this is what you're asking about:
Basically C++ doesn't allow variable-sized arrays. Any array in C++ has to be given a very specific size. But you can use pointers to work around that. Consider the following code:
int *arry = new int[10];
That just created an array of ints with 10 elements, and is pretty much the same exact thing as this:
int arry[] = int[10];
The only difference is that each one will use a different set of syntax. However imagine trying to do this:
Class class:
{
public:
void initArry(int size);
private:
int arry[];
};
void class::initArry(int size)
{
arry = int[size]; // bad code
}
For whatever reason C++ was designed to not allow regular arrays to be assigned sizes that are determined at runtime. Instead they have to be assigned sizes upon being coded. However the other way to make an array in C++ - using pointers - does not have this problem:
Class class:
{
public:
~class();
void initArry(int size);
private:
int *arry;
};
class::~class()
{
delete []arry;
}
void class::initArry(int size)
{
arry = new int[size]; // good code
}
You have to do some memory cleanup in the second example, hence why I included the destructor, but by using pointers that way you can size the array at runtime (with a variable size). This is called a dynamic array, and it is said that memory here is allocated dynamically. The other kind is a static array.
As far as 2-dimensional arrays go, you can handle it kind of like this:
Class class:
{
public:
~class();
void initArrays(int size1, int size2);
private:
int **arry;
};
class::~class()
{
delete [] arry[0];
delete [] arry[1];
delete [] arry;
}
void class::initArrays(int size1, int size2)
{
arry = new int*[2];
arry[0] = new int[size1];
arry[1] = new int[size2];
}
Disclaimer though: I haven't done much with this language in a while, so I may be slightly incorrect on some of the syntax.