I have written this code to declare a pointer, p
, and then dynamically allocate 4 bytes of memory for type int to then store some data in it. p
should point to an address which holds the data 6
of type int. The program should then print out the data from the pointer variable using the dereferencing operator
. I have also included the free()
function to release allocated memory from the heap. I don't understand why I'm receiving a bus error. The same code has been executed by a peer and it has worked perfectly fine. I'm using a Mac M2 and running the code on vscode
. What could be causing this error?
#include <stdio.h>
#include <stdlib.h>
void foo(int *a){
a = (int*)malloc(sizeof(int));
}
int main(){
int *p;
foo(p);
*p = 6;
printf("%d",*p);
free(p);
return(0);
}
Here's the error message: zsh: bus error
Note that if I were to remove the foo()
function and replace the calling line with p = (int*)malloc(sizeof(int));
then the program works perfectly fine. Why is it that having it in the previous method results in a bus error?
In C arguments are passed to functions by value. It means relative to your program that the function foo
deals with a copy of the value of the pointer p
declared in main
.
So any changes of the copy within the function leave the original pointer unchanged.
You may imagine the function and its call the following way
foo(p);
//...
void foo( /*int *a */ ){
int *a = p;
a = (int*)malloc(sizeof(int));
}
As you can see it is the local variable a
declared within the function that was changed. The original pointer p
stays unchanged. Function parameters are local variables of the function.
So as the pointer p
stays unchanged and is not initialized then dereferencing the pointer like for example
*p = 6;
results in the bus error.
To change an object (including a pointer) within a function you need to pass it by reference.
In C passing by reference means passing an object indirectly through a pointer to it. Thus dereferencing the passed pointer you get a direct access to the object pointed to by the pointer and can change it.
So your program should look the following way
#include <stdio.h>
#include <stdlib.h>
void foo( int **a )
{
*a = malloc(sizeof(int));
}
int main( void )
{
int *p;
foo( &p );
if ( p != NULL )
{
*p = 6;
printf( "%d\n", *p );
}
free(p);
return 0;
}
Pay attention to two aspects.
The first one is that the function main
without parameters shall be declared as
int main( void )
And the second one is that in C (opposite to C++) you need not to cast the pointer returned from the function malloc
. That is you may write
*a = malloc(sizeof(int));
And also you should check whether the pointer p
changed within the function is not a null pointer before dereferencing it in main
. On the other hand, the function free
may be called for a null pointer.