Basic pointer exercise error [duplicate] - c

This question already has answers here:
How to access a local variable from a different function using pointers?
(10 answers)
Closed 6 years ago.
I started studying pointers and I got in some trouble with the next code:
#include <stdio.h>
int * g()
{
int a = 10;
return &a;
}
void main()
{
int *p;
p=g();
printf("%d",*p);
}
It returns the error segmentation fault. core dumped
I would really apreciate any help. Have a nice day!

You are returning the address of a local variable. When you leave the function your code does not know this variable anymore, thus the segmentation fault.
You would have to give a pointer to this function as a parameter or dynamically create memory for this variable in the heap.
e.g.
void g(int* p) {
*p = 10;
}
int main() {
int a;
g(&a);
printf("%d", a);
return 0;
}
or
int* g() {
int* p = (int*) malloc(sizeof(int));
*p = 10;
return p;
}
int main() {
int* p;
p = g();
printf("%d", *p);
free(p)
return 0;
}

Related

shows variable uninitialized when calling a function that uses malloc [duplicate]

This question already has answers here:
Changing address contained by pointer using function
(5 answers)
Closed last year.
# include<stdio.h>
# include<stdlib.h>
void fun(int *a)
{
a = (int*)malloc(sizeof(int));
}
int main(void)
{
int *p;
fun(p);
*p = 6;
printf("%d\n",*p);
free(p);
return(0);
}
In vs code this shows error because int *p is uninitialized and tells me to initialize the variable 'p' to NULL to silence this warning. But when I did that it compiled but showed segmentation fault, likely because I'm assigning 6 to the null address, so how do I fix this?
This function
void fun(int *a)
{
a = (int*)malloc(sizeof(int));
}
changes its own local variable (parameter) a. That is the function deals with a copy of the value of the passed pointer p
int *p;
fun(p);
The pointer p stays unchanged and uninitialized.
To make the program correct you need to change the code the following way
void fun(int **a)
{
*a = (int*)malloc(sizeof(int));
}
//...
int *p;
fun( &p);
Though in this case it would be better to declare and define the function like
int * fun( void )
{
return malloc(sizeof(int));
}
//...
int *p = fun();
if ( p )
{
*p = 6;
printf("%d\n",*p);
}
free(p);

How to modify a heap pointer from a function [duplicate]

This question already has answers here:
How do I modify a pointer that has been passed into a function in C?
(7 answers)
Closed 3 years ago.
How can I change a heap allocated global pointer from within a function? Here is what I am working with, (call to modify_p seg faults and I can't see much in the debugger):
#include <stdio.h>
#include <stdlib.h>
int *p;
void set_p(int *p, int sz) {
p = malloc(sz * sizeof(int));
}
void modify_p(int *p) {
p[0] = 2;
}
int main(int argc, char *argv[])
{
set_p(p, 3);
modify_p(p);
//printf("%d\n", p[0]);
// should print 2
return 0;
}
Thanks
The issue is that you pass a copy of p to set_p. So the original p is never modified and never points to valid memory, and the copy is lost at the end of set_p, leaking the memory. Instead, pass a pointer to p (so a pointer to a pointer), like this:
void set_p(int **p, int sz) {
*p = malloc(sz * sizeof(int));
}
And call the function like this:
set_p(&p, 3);
Then you get the expected result.
One way would be to do this:
#include <stdio.h>
#include <stdlib.h>
int *p;
void set_p(int sz) {
p = malloc(sz * sizeof(int));
}
void modify_p() {
p[0] = 2;
}
int main(int argc, char *argv[])
{
set_p(3);
modify_p();
printf("%d\n", p[0]);
// should print 2
return 0;
}
As p is declared outside of any function, you can write directly to it. When you do set_p(p, 3);, the set_p function will have it's local copy of the variable.
If you want to change what a pointer points to, you have to pass the address of the pointer (as shown by Blaze).

How does memory allocation work in c? [duplicate]

This question already has an answer here:
How to access a structures' members outside of its original function?
(1 answer)
Closed 6 years ago.
#include<stdio.h>
int * display();
main()
{
printf("\nHello\n");
int * a = display();
printf("%d", *a);
}
int * display()
{
printf("\n Hi \n");
int b = 10;
return &b;
}
Can anyone tell me how does memory allocation work in c?
I'm sure we can access the value of b(in this program), then why can't we access the address of it? I get an error (Segmentation fault).
What is the concept behind it?
I'm a beginner.
You shouldn't return pointer to an automatic local variable. It will no longer exist once function return and therefore will invoke undefined behavior.
You can allocate memory dynamically and then return pointer:
int * display()
{
printf("\n Hi \n");
int *b = malloc(sizeof(int));
*b = 10;
return b;
}

Returning a pointer from a function

This is in reference to this question: Why is a pointer to pointer needed to allocate memory in this function?
The answer to the question explained why this didn't work:
void three(int * p)
{
p = (int *) malloc(sizeof(int));
*p = 3;
}
void main()
{
int *p = 0;
three(p);
printf("%d", *p);
}
... but this works:
void three(int ** p)
{
*p = (int *) malloc(sizeof(int));
**p = 3;
}
void main()
{
int *p = 0;
three(&p);
printf("%d", *p);
}
This also works, by returning a pointer from the function. Why is that?
int* three(int * p)
{
p = (int *) malloc(sizeof(int));
*p = 3;
return p;
}
void main()
{
int *p = 0;
p = three(p);
printf("%d", *p);
}
int* three(int * p)
{
p = (int *) malloc(sizeof(int));
*p=3;
return p;
}
Because here you're returning a copy of the pointer p and this pointer now points to valid memory, which contains the value 3.
You originally passed in a copy of your p as an argument, so you're not changing the one you passed in, but a copy. Then you return that copy, and assign it.
From the comment, which is a very valid point, this will also work just as well:
int* three()
{
//no need to pass anything in. Just return it.
int * p = (int *) malloc(sizeof(int));
*p=3;
return p;
}
They're completely different (and if you truly understand why the first works, you'd see there's no connection).
By returning, you're not attempting to modify the already existing pointer from inside the function. You're just returning a new pointer, and assigning its value outside.
Look at it as a question of scope.
In main() you have a pointer p.
int *p = 0;
p in main is set to NULL. When you make a call to the three function passing it p:
three(p);
You are passing a pointer to NULL. What happens to it is outside the scope of main(). main() does not know, nor does it care what happens. main() only cares about its copy of p, which at this point is still set to NULL.
Unless I reassign p within the scope of main() (including handing off the address of p), p is still just a pointer pointing to NULL.
If I give you this code:
void main()
{
int *p = 0;
funcX(p);
printf("%d",*p);
}
You can tell me definitively what is going to happen (Segmentation fault) without ever knowing what funcX() does because we're passing a copy of the pointer to this function, but a copy doesn't affect the original.
But if I give you this code:
void main()
{
int *p = 0;
funcX(&p);
printf("%d",*p);
}
You can't tell me what will happen unless you know what funcX() is doing.
That make sense?

Returning this pointer from a function

I am trying to return a pointer from a function. But I am getting a segmentation fault. Someone please tell what is wrong with the code
#include <stdio.h>
int *fun();
main()
{
int *ptr;
ptr = fun();
printf("%d", *ptr);
}
int *fun()
{
int *point;
*point = 12;
return point;
}
Allocate memory before using the pointer. If you don't allocate memory *point = 12 is undefined behavior.
int *fun()
{
int *point = malloc(sizeof *point); /* Mandatory. */
*point=12;
return point;
}
Also your printf is wrong. You need to dereference (*) the pointer.
printf("%d", *ptr);
^
Although returning a pointer to a local object is bad practice, it didn't cause the kaboom here. Here's why you got a segfault:
int *fun()
{
int *point;
*point=12; <<<<<< your program crashed here.
return point;
}
The local pointer goes out of scope, but the real issue is dereferencing a pointer that was never initialized. What is the value of point? Who knows. If the value did not map to a valid memory location, you will get a SEGFAULT. If by luck it mapped to something valid, then you just corrupted memory by overwriting that place with your assignment to 12.
Since the pointer returned was immediately used, in this case you could get away with returning a local pointer. However, it is bad practice because if that pointer was reused after another function call reused that memory in the stack, the behavior of the program would be undefined.
int *fun()
{
int point;
point = 12;
return (&point);
}
or almost identically:
int *fun()
{
int point;
int *point_ptr;
point_ptr = &point;
*point_ptr = 12;
return (point_ptr);
}
Another bad practice but safer method would be to declare the integer value as a static variable, and it would then not be on the stack and would be safe from being used by another function:
int *fun()
{
static int point;
int *point_ptr;
point_ptr = &point;
*point_ptr = 12;
return (point_ptr);
}
or
int *fun()
{
static int point;
point = 12;
return (&point);
}
As others have mentioned, the "right" way to do this would be to allocate memory on the heap, via malloc.
It is not allocating memory at assignment of value 12 to integer pointer. Therefore it crashes, because it's not finding any memory.
You can try this:
#include<stdio.h>
#include<stdlib.h>
int *fun();
int main()
{
int *ptr;
ptr=fun();
printf("\n\t\t%d\n",*ptr);
}
int *fun()
{
int ptr;
ptr=12;
return(&ptr);
}
To my knowledge the use of the keyword new, does relatively the same thing as malloc(sizeof identifier). The code below demonstrates how to use the keyword new.
void main(void){
int* test;
test = tester();
printf("%d",*test);
system("pause");
return;
}
int* tester(void){
int *retMe;
retMe = new int;//<----Here retMe is getting malloc for integer type
*retMe = 12;<---- Initializes retMe... Note * dereferences retMe
return retMe;
}

Resources