Returning this pointer from a function - c

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;
}

Related

Malloc within function not changing pointer value

So when I pass a data type like a struct to assign some memory to it I find that the pointer doesn't change within the main scope. This further becomes a problem when I try to free the memory but obviously if its using the original pointer it will be pointing at the stack address.
void allocate(int *value){
value = malloc(10 * sizeof(int));
}
int main(){
int val2;
allocate(&val2);
free(&val2);
return 0;
}
I can fix this by using a double pointer to be passed into the allocate function but some course work I'm doing requires to only pass a pointer and I cant get it to update the pointer when it returns to main. I have looked around for a while but cant find a straight forward answer, I feel like my coursework is wrong but that might be my lack of understanding.
The requirement to "only pass a pointer" seems contrived, and you could argue that a pointer to pointer (not a "double pointer") is a pointer, but perhaps you could use void * to punch a hole in the type system. Or use a struct:
#include <stdlib.h>
#include <stdio.h>
struct intbuffer {
int *d;
size_t cap;
};
void *
xmalloc(size_t s)
{
void *r = malloc(s);
if( r == NULL ){
perror("malloc");
exit(1);
}
return r;
}
void
allocate(void *p, size_t s)
{
*(int **)p = xmalloc(s * sizeof(int));
}
void
allocate2(struct intbuffer *p)
{
p->d = xmalloc(p->cap * sizeof *p->d);
}
int
main(void)
{
int *val2;
struct intbuffer v;
allocate(&val2, 10);
free(val2);
v.cap = 10; /* Horrible api!! */
allocate2(&v);
free(v.d);
return 0;
}
Note that setting the capacity in the struct prior to making the call to allocate is a violation of many principles of software design, but this whole thing is absurdly contrived due to the bizarre artificial limitations.
There are not enough *'s in each place, but you will have to figure out what that means.
void allocate(int** value){
*value = malloc(10 * sizeof(int));
}
int main(){
int* val2;
allocate(&val2);
free(val2);
return 0;
}

In C, I understand why not to return the address of a local variable in a pointer returning function, how can I fix it though?

I have the following code:
int* foo(){
int x = 15;
return &x; }
Which I understand why not to do since the local variable address gets erased from the stack after the function finishes and it becomes a dangling pointer. The question is, how do I not make it a dangling variable without making x a static variable
The blessed ways are:
return a value and not an address
int foo(){
int x = 15;
return x;
}
have the caller to provide an address
int *foo(int *x) {
*x = 15;
return x;
}
or
void foo(int *x) {
*x = 15;
}
Return dynamic (allocated) memory:
int *foo() {
int *x = malloc(sizeof(*x));
// should test valid allocation but omitted for brievety
*x = 15;
return x;
}
Beware, the caller will take ownership or the allocated memory and is responsable to free it later.
Either allocate memory from the heap inside the function
int *f() {
int *foo = malloc(sizeof(int));
if(!foo) {
// Do appropriate error handling here
}
return foo;
}
Don't forget to free it at some point though.
Or you pass in a pointer to a variable living outside the function:
void f(int *foo) {
*foo = 42;
}
void g() {
int goo;
f(&goo);
}

Returning pointers back to itself

My coding assignments came with it's header file, meaning we need to use the same data types, and not vary anything.
There is a lot of pointers, (mainly a lot of void *). Meaning things are confusing, more than difficult.
we have to do a separate function, just to increment the value referenced by a pointer. But given the nature of program, I don't want to constantly make new pointers.
The code is as follows:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void* intal_create(const char* );
void* intal_increment(void* );
void *intal_create(const char* str)
{
int a;
a=atoi(str);
return &a;
}
void *intal_increment(void *intal)
{
int *a= (int *)intal;//new pointer;
++*a;
//value referenced has been incremented;
*(int *)intal=*a;
return intal;
}
int main()
{
int * x;// void * return a pointer, need a pointert to int to pick it up
char *dummy;
gets(dummy);
x=(int *)intal_create(dummy);
printf("integer return is %d\n",*(int *)x);
printf("address stored is %p\n",(int *)x);
x=(int *)intal_increment(x);
printf("integer return is %d\n",*(int *)x);
printf("address stored is %p\n",(int *)x);
}
I wanted x to be the parameter called, and also for it to store the return value. The printf address is merely for my understanding.
The segmentation faults never end, and from my understanding, I'm just returning a pointer and asking a pointer to stop the return pointer
By incorporating all the comments. Mainly allocating memory to dummy before passing it gets() function and allocating memory in heap for the return pointer of intal_create.These two fixes solve the issue. Have a look at the following code for reference.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void* intal_create(const char* );
void* intal_increment(void* );
void *intal_create(const char* str)
{
int *a = (int *)malloc(sizeof(int));
*a = atoi(str);
return a;
}
void *intal_increment(void *intal)
{
//Here i am not allocating
int *a = (int *)intal;//new pointer;
(*a)++;
return intal;
}
int main()
{
int * x;// void * return a pointer, need a pointert to int to pick it up
char dummy[20] = {0};
fgets(dummy,5,stdin);
x = (int *)intal_create(dummy);
printf("integer return is %d\n",*x);
printf("address stored is %p\n",(void*)x);
x=(int *)intal_increment(x);
printf("integer return is %d\n",*x);
printf("address stored is %p\n",(void *)x);
//Make sure you deallocate the memory allocated in the intal_create function.
free(x);
}

Assign the address of local variable to global pointer in C?

I'm newbie in C language. If I assign the address of local variable to global pointer, What happens? Like,
#include <stdio.h>
void func();
int *ptr;
int main()
{
func();
}
void func()
{
int i = 0;
ptr = &i;
}
Is it correct way to assign the address of local variable to global pointer?
It just does what you do, there is nothing wrong about it, except that it probably is not what you want.
So it just assigns the address of i to ptr at the point you assign it. When you leave func this pointer gets invalid.
Note This behaviour is fully defined: The address of i at the place you assign it to the global variable is defined, and so you can assign it. The problem only comes into play later, when you try to dereference the variable after you left the function func. As long as you only use the global variable in func there is no problem in this (except that a global variable is really meaningless).
At this point, this variable doesn't exist anymore. And it is very likely that you either get a segfault or at least you get some strange numbers (because you have overwritten the old stack frame with some other values) in this case.
Just as a side note: What I mean with this stack frame thing. You can try this code on most compilers (without optimizations!)
#include <stdio.h>
int *ptr;
void f1() {
int i = 0;
ptr = &i;
}
void f2() {
int i = 1;
}
int main() {
f1();
printf("%d\n", *ptr);
f2();
printf("%d\n", *ptr);
}
Without optimizations, this will most probably print
0
1
Because the variable i will have the same address when calling f1 and f2 from main().
With optimizations, the call to f2() will be optimized.
Still: This is undefined behavior and must not be done.
Your syntax is correct, but the local variable ceases to exist because it belongs within the scope of the function call's code block. To resolve this, one option is to make the local variable static:
#include <stdio.h>
void func();
int *ptr;
int main()
{
func();
}
void func()
{
static int i = 0;
ptr = &i;
}
Another option would be to allocate new memory within the function call, setting the global pointer to the address of that newly allocated memory:
#include <stdio.h>
void func();
int *ptr = NULL;
int main()
{
func();
}
void func()
{
if(ptr != NULL)
free(ptr);
int *i = (int *)malloc(sizeof(int));
ptr = i;
}
What you've got is syntactically correct, and the code as written is semantically valid (but since ptr is never used, it is a bit pointless).
If you access ptr when it contains a pointer that has gone out of scope, you get undefined behaviour.
However, consider a slightly larger code fragment. Here, the code that sets ptr calls a function that uses ptr, and the variable that ptr points to is still defined, so there is no problem using the pointer.
#include <stdio.h>
void func(void);
void use_pointer(void);
int *ptr;
int main(void)
{
func(); // NB: argument not allowed with prototype!
int i = 20;
printf("%s: A %d\n", __func__, i);
ptr = &i;
use_pointer();
printf("%s: B %d\n", __func__, i);
}
void func(void)
{
int i = 0;
printf("%s: A %d\n", __func__, i);
ptr = &i;
use_pointer();
printf("%s: B %d\n", __func__, i);
}
void use_pointer(void)
{
printf("ptr = %p; *ptr = %d\n", (void *)ptr, *ptr);
*ptr = 42;
}
This is legitimate code — though using global variables is something you should generally avoid and perfectly well could avoid.
Sample output:
func: A 0
ptr = 0x7fff55be74ac; *ptr = 0
func: B 42
main: A 20
ptr = 0x7fff55be74cc; *ptr = 20
main: B 42

Is this program correct?

Can someone tell me, if function fun() is correct?
#include <stdio.h>
#include <stdlib.h>
int *fun(int *, int *, int, int);
int main(void) {
int v1[] = {1,2,3,4,5};
int v2[] = {6,7,8,9,10};
int v1Size = sizeof(v1)/sizeof(v1[0]);
int v2Size = sizeof(v2)/sizeof(v2[0]);
int *v = fun(v1, v2, v1Size, v2Size);
if(v == NULL)
exit(EXIT_FAILURE);
for(size_t i = 0; i < v1Size; ++i)
printf("%d ", v[i]);
}
int *fun(int *v1, int *v2, int v1Size, int v2Size){
if(v1Size!=v2Size)
return NULL;
const int size = v1Size;
int v[size];
for(int i=0; i<size; i++)
v[i]=v1[i]+v2[i];
int *p = v;
return p;
}
For me, it returns the pointer that points memory that will be freed after leaving the fuction body. But valgrind doesn't show any error and it works just fine.
works just fine
Stop !! it's one of the possible outcome of invoking undefined behavior.
As you correctly mentioned, the returned pointer won't be valid (VLAs reside in auto scope (stack), in general, as in gcc) after returning from fun(). Using the return value will lead to UB.
Returning the address of a local variable is not "fine". Once the function exits, v no longer exists, so any pointer to it is no longer valid. Obviously, the storage that v occupied still exists, and as long as nothing else overwrites that storage, your code will appear to function correctly.
Note the emphasis on appear. Your code could just as easily crash, or give garbled output, or otherwise be put into a bad state. It depends on how you use that returned pointer value.
v has auto storage duration, meaning storage for it is allocated at function entry and released at function exit. Valgrind isn't going to say boo about it, because it's not the kind of thing Valgrind checks.

Resources