C, pass by value, in Linux [closed] - c

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 1 year ago.
Improve this question
I have a function as follows:
void foo (int *check){
*check= 9;
printf("*check: %d\n",*check);
//when I print "*check" here, the value changes as 9.
}
This is the main function.
void main () {
int check=5;
foo(&check);
printf("check: %d\n",check);
//when I print "check", gives me 5.
}
I want to change the value of "check" variable but it does not work. Where am I making mistake? Thank you!
I am using makefile while running it.
Edit: malloc is deleted now it gives me Segmentation fault (core dumped) error

When you malloc within foo, the dereference now points to the value malloced within the function's scope. This means that the value within the function is changed and not the value outside of the function. To correct this, you don't need to malloc within the function to change the value of check:
void foo (int *check) {
*check= 9;
}
void main () {
int check = 5;
foo(&check); // check is now 9
}

You are doing everything just fine, the only thing that is wrong is trying to malloc the variable you passed to the function , since it is already allocated on stack. In order to do what you're trying to do, you should declare the integer as pointer to integer (int *check) outside the function, and avoid using the & character when calling the function with the pointer as parameter.

To change a variable through a function you need to pass it by reference, not value. Your title and code do not match.
Here is a version with both kinds of arguments, side by side:
#include <stdio.h>
int foo(int *ref, int val) {
*ref = 1122; // by reference
val = 1155; // by value
printf("inside:\n%d %d\n", *ref, val);
return val; // otherwise "val=1155" is lost
}
int main(void) {
int ree = 12; // "referencee"
int v = 15;
printf("main:\n%d\n", foo(&ree, v)); // return value (1155)
printf("%d %d\n", ree, v); // 1122 and 15
}
ree is passed as &ree to ref; this address/pointer gets dereferenced inside the function with *ref to change ree's value.

You passed the variable check to the function foo by reference through a pointer to it
int check=5;
foo(&check);
So dereferencing the pointer you could get a direct access to the variable check and could change it like
*check= 9;
However within the function you reassigned the pointer with a new address of a dynamically allocated memory
check= malloc(sizeof(int));
So now the pointer check doe not point to the original object passed to the function by reference. As a result this statement
*check= 9;
changes the dynamically allocated object of the type int instead of changing the variable passed to the function by reference.
Edit: malloc is deleted now it gives me Segmentation fault (core
dumped) error
It is a bad idea to change such dramatically the code in the question because it will only confuse readers of the question and answers. Neither segmentation fault should occur. It seems the new provided code in the question does not correspond to the actual code that generates a segmentation fault.
Here is a demonstrative program. It compiles and runs successfully.
#include <stdio.h>
void foo ( int *check )
{
*check = 9;
printf( "Inside foo check = %d\n", *check );
}
int main(void)
{
int check = 5;
printf( "Before foo check = %d\n", check );
foo( &check );
printf( "After foo check = %d\n", check );
return 0;
}
The program output is
Before foo check = 5
Inside foo check = 9
After foo check = 9

Related

Getting head value is equal to NULL always in the linked list? [duplicate]

I am learning C. I was writing code to create a linked list when i came across a segmentation fault. I found a solution to my problem in this question.
I was trying to pass a pointer by reference. The solution says that we can't do so. We have to pass a pointer to a pointer. This solution worked for me.
However, I don't understand why is it so. Can anyone tell the reason?
From The C Programming Language - Second Edition (K&R 2):
5.2 Pointers and Function Arguments
Since C passes arguments to functions by value, there is no direct way
for the called function to alter a variable in the calling function.
...
Pointer arguments enable a function to access and change objects in
the function that called it.
If you understand that:
void fn1(int x) {
x = 5; /* a in main is not affected */
}
void fn2(int *x) {
*x = 5; /* a in main is affected */
}
int main(void) {
int a;
fn1(a);
fn2(&a);
return 0;
}
for the same reason:
void fn1(element *x) {
x = malloc(sizeof(element)); /* a in main is not affected */
}
void fn2(element **x) {
*x = malloc(sizeof(element)); /* a in main is affected */
}
int main(void) {
element *a;
fn1(a);
fn2(&a);
return 0;
}
As you can see, there is no difference between an int and a pointer to element, in the first example you need to pass a pointer to int, in the second one you need to pass a pointer to pointer to element.

Global variable as an argument of function call in C [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
"While passing global variable in function parameter, is it passed by reference or value ?"
It is passed by value. The following code shows that this is the case:
#include <stdio.h>
int global = 5;
void foo(int bar){
bar = 6;
printf("bar = %d\nglobal = %d", bar, global);
}
int main(){
foo(global);
return 0;
}
The output is:
bar = 6
global = 5
In this code global was passed as a parameter for foo, we called this parameter bar. So at the beginning global and bar are two different variables both having the value 5. But then bar is assigned the value 6 and since the argument was referenced by value, global stays at 5.
To pass the variable by reference, use pointers:
#include <stdio.h>
int global = 5;
void foo(int *bar){
*bar = 6;
printf("bar = %d\nglobal = %d", *bar, global);
}
int main(){
foo(&global);
return 0;
}
Now the output is:
bar = 6
global = 6
Both local and global variables are passed to functions by value in C. If you need to pass by reference, you will need to use pointers.
How the variable is/must be passed, depends on the function, not on the variable:
int gMyVar;
void foo(int a); // says "call me by value"
void bar(int *b); // says "call my by reference"
foo requires an int to be passed. you must call it as foo(gMyVar).
bar requires a pointer to an int. You must call it as bar(&gMyVar).
So, as other answers indicated, C always passes a value, however, the value can be the value of a variable (call by value) or can be a pointer to a variable (call by reference).
First of all, Why do we need to pass Global variable in a function? we can directly access it any where in the program if you dont know.
#include <stdio.h>
int x = 10; //global variable
void fun()
{
printf("%d",x); // direct access
}
int main(void) {
fun(); // no argument required
return 0;
}
Output
10
For demo http://ideone.com/VLWqNO

Use of automatic variable outside its scope in C [duplicate]

This question already has answers here:
What happens when a variable goes out of scope?
(3 answers)
Closed 6 years ago.
I am studying the working of an automatic variable. I know that it is only accessible inside the block or function in which it is declared and its lifetime is within that same function or block. So the following piece of code I am trying to check.
/Declaration of header files/
void testfn(void);
int *p;
int main(void)
{
testfn();
print("%d\n",*p);
return 0;
}
void testfn(void)
{
int x=444;
p=&x;
}
The output is - 444
I am wondering that when the testfn(); exits,the variable x will be destroyed. Then how in main function the pointer (*p) prints 444.
How this works...or if I am missing something.
Please clarify my doubt.
Thanks
It is coincidence that the original value still remains. With another compiler, or with another compilation configuration, it could take any other value or the program could just crash.
If between the testfn and printf functions you call any other function that does something with its local variables, you might see that the 444 value is not obtained anymore. But this is just, again, coincidence.
p points to the stack where x was stored. If the memory location hasn't been used for something else you will most likely get 444.
Try to insert another function call before printing p and see what happens:
#include <stdio.h>
#include <math.h>
void foo() {
int y=123;
}
void testfn(void);
int *p;
int main(void)
{
testfn();
foo();
printf("%d\n",*p);
return 0;
}
void testfn(void)
{
int x=444;
p=&x;
}
On my machine, the output is now:
123
Since the code results in undefined behaviour, the result could be different if I try this on another platform. But you can see that undefined behaviour can lead to strange bugs.
The memory location that was previously reserved for variable x is not overwritten yet. But it may be at any time. That's why your code leads to undefined behaviour.
In the following example, the memory location that was previously reserved for variable x will be overwritten by the value that is assigned to the variable y. Since the pointer p still points to that location, *p will evaluate to this new value:
#include <stdio.h>
int *p;
void test1(void) {
int x = 444;
p = &x;
}
void test2() {
int y = 15;
}
int main(void) {
test1();
test2();
printf("%d\n",*p);
return 0;
}
The fact that the value still remains is completly coincidental (not guaranteed) because nothing has overwritten it yet.
You can not count on this, it may fail, may print garbage or may crash your program or pc even.
Don't use this, it is considered undefined behavior.

Parameter passing in C functions [duplicate]

This question already has answers here:
What (actually) happens, when a function with the warning "control reaches end of non-void function" is called?
(7 answers)
Closed 7 years ago.
I am newbie. So please bear with me,
#include<stdio.h>
int abc(int k)
{
k++;
}
int main()
{
int a=1;
printf("%d",abc(a));
return 0;
}
Output of above program is : 1
My question is shouldn't the output should be '2' as the actual parameter is passing the value of '1' to the formal parameter and it has to be incremented by the function abc.
And when I change the function call to
printf("%d",abc(1));
The output is some garbage value.
How does parameter passing work here? Please explain.
The unexpected results you are getting are not resulting from the "parameter passing", but from the fact that the abc function does not return any value. You should use return k; statement to get the output you are expecting. But as for parameter passing, they are passed by value, i.e. the passed value is copied to a temporary location k (visible in the function only), and not modified outside of it.
The code example you have passes a by value. You could think of it as a copy of a. You code modified with comments:
#include<stdio.h>
int abc(int k)
{
// k is a copy of a, it is not a, since k is a copy, it has the
// value of a at the point of the copy. So, k is 1
k++; // k is now 2
return k; // return the computed value to the caller and destroy k
}
int main()
{
int a=1;
// as previously written, without the return statement in abc()
// this function returned nothing. So, the compiler just arranges
// for something to be used from the stack where the return would
// have placed 2. (I'm not terribly familiar
// with assembly and so I'm not sure which register it would use).
// That's why you get non-nonsensical data, whatever is in memory is
// what you get and without the return statement, there's nothing
// meaningful there.
// Also, as I commented above, abc() takes a **copy** of a. Thus,
// the contents of a are unmodified. See how the printf() is
// changed. What does it print?
printf("%d %d",abc(a), a);
return 0;
}

simple pointers to pointers

I know why this works:
#include <stdio.h>
void cool_number(int **number) {
int value = 42;
int *p = &value;
*number = p;
}
int main () {
int *number;
cool_number(&number);
printf("number is %d\n", *number);
return 0;
}
What I don't understand is why this doesn't (in my machine it prints 3700 or something like that).
#include <stdio.h>
void cool_number(int **number) {
int value = 42;
int *p = &value;
int **x = &p;
number = x;
}
int main () {
int *number;
cool_number(&number);
printf("number is %d\n", *number);
return 0;
}
Why aren't both equivalent?
both are evil as they capture the address of a stack variable.
Second one doesn't do what you expect because you are assigning directly to the parameter number, which is only temporary, the first one changes something the parameter number pointers to, which is the same thing as number in main points to.
I assume they're not equivalent because number is passed by value, on the stack, as is standard for function parameters. Any changes that you make directly to number inside of cool_number() are modifying the local copy on the stack, and are not reflected in the value of number in main().
You get around this in the first example by dereferencing number, which tells the computer to modify some specific location in memory that you also happen to have a pointer to back in main(). You don't have this in the second example, so all that happens is that you make the local number pointer point to somewhere else, without actually updating any memory location being referred to back in main(). Thus nothing you do shows up once you get back to main().
And since value is local to the cool_number() function, setting a reference to it that will be accessed after cool_number() returns isn't guaranteed to work and certainly shouldn't be used in any code outside of a trivial/toy example. But in this specific instance it's not really related to why you're seeing different results between the two pieces of code.
As I understand, in both cases, your code is wrong.
In the first case, you are returning an address to a variable allocated on stack, which will be deallocated as soon as the function returns.
In the second case, the error of the first case exists, plus you are passing number by value, so an updation to number will not get reflected in the caller function.
In 'C', arguments are always passed by value. So, you cannot update the argument passed as it is. For Ex:
int func(int a)
{
a = 5; // In this case the value 5 will not be reflected in the caller as what is updated is the local copy of a on the stack
}
int func(int *a)
{
*a = 5; // This update will show in caller as you are directly updating the memory pointed to by a
a = malloc(4); //This update will not show in caller as again you are updating the local copy of stack
}
#include <stdio.h>
void cool_number(int **number) {
int value = 42; /* this "value" hold 42 value,
and it lifetime is only in this function */
int *p = &value; /* here we get the address of "value" in memory */
*number = p;
}
int main () {
int *number;
cool_number(&number); /* after this function the "value" in memory had been recyled
and may be used by other program */
printf("number is %d\n", *number); /* so when we print value here it will be
a unpredictable value, somehow may be crash */
return 0;
}
both the same principle

Resources