Reputation: 309
As far as I know Heaps are supposed to be global in nature, aren't they? So we should be able to access the heap memory anywhere we want in our functions. Then why does the following code segfault (Segmentation Fault)?
#include <stdio.h>
using namespace std;
void A(int* x)
{
x = new int[10];
for(int i = 0; i< 10; i++)
{
x[i] = i;
}
}
void B(int *x)
{
printf("%d", x[8]);
}
int main()
{
int* a = NULL;
A(a);
B(a);
return 0;
}
Upvotes: 3
Views: 885
Reputation: 206577
Question: As far as I know Heaps are supposed to be global in nature, aren't they?
Answer: Yes.
Statement: So we should be able to access the heap memory anywhere we want in our functions.
Respons: Yes, we will be able to, as long as we know the heap memory value.
Question: Then why does the following code segfault (Segmentation Fault)?
Answer: Allocating heap memory in one function does not guarantee that the memory value is visible from other functions. The address returned by operator new
has to be somehow made available to other functions. You can do this in couple of ways:
Change the argument type to int*& a
, as suggested by Subhajit.
Let A
return the allocated memory address.
int* A()
{
int* x = new int[10];
for(int i = 0; i< 10; i++)
{
x[i] = i;
}
return x;
}
Upvotes: 2
Reputation: 14619
As other answer(s) indicate, indeed the problem is that the memory allocated in A()
is not passed to B()
.
But it's really excellent to note that you can detect this problem using static analysis, with freely available tools.
When I ran clang++
version 3.4 on your example, it gives:
$ make
clang++ -Wall -Wextra --analyze -c -o go.o go.cpp
go.cpp:16:16: warning: Array access (from variable 'x') results in a null pointer dereference
printf("%d", x[8]);
^~~~
1 warning generated.
How awesome is that‽ In this particular standalone example the additional time for the compiler to evaluate the paths was negligible. It may be a bit more overhead on "real" code (not synthetic examples like these). But it's almost certainly worth it for most users.
Upvotes: 2
Reputation: 320
Both A(a) and B(a) call are By Value for a. So, any change inside A() or B() will not affect from the caller.
Please call as,
void A(int*& a);
Upvotes: 1
Reputation: 121971
A segmentation fault occurs because the pointer a
is being passed by value so the changes made within A()
are not visible to the caller, resulting in a NULL
pointer being dereferenced within B()
. To correct, pass the pointer by reference to A()
:
void A(int*& x)
Upvotes: 9