Change value in main using void sub-function - c

I am having trouble with this problem:
#include <stdio.h>
void change_number(int *x);
int main()
{
int x;
printf("Enter the number x: ")
scanf("%d", &x);
printf("In the main program: x = %d\n", x);
change_number(&x);
printf("In the main program: x = %d\n", x);
return 0;
}
void change_number(int *x)
{
x = *x+3;
printf("In the subroutine: x = %d\n", x);
}
Expected output:
Enter the number x: 555
In the main program: x = 555
In the subroutine: x = 558
In the main program: x = 558
Two notes:
I cannot modify main, or anything that comes before it. I can only modify the void change_number function, and the code inside it is my own code.
I cannot get the required output – my code only outputs x+3 in the subroutine, but doesn't change it in the main program.
How would I go about changing the value in the main routine? Please keep in mind that I am very new to C, and don't know many things yet (in fact, I just covered pointers yesterday).

The code
void change_number(int *x)
{
x = *x+3;
printf("In the subroutine: x = %d\n", x);
}
should read
void change_number(int *x)
{
*x = *x+3;
printf("In the subroutine: *x = %d\n", *x);
}
This will use the pointers as intended (you need to dereference them on the LHS as well)

I think an answer to the OP question needs a little bit explanation as C syntax may be confusing at times:
The function is declared as
void change_number(int *x)
The * means that the input parameter x is a pointer to a variable of type int. In other words x represents a location in memory.
Inside the function:
x is the address in memory of the int value
*x is the "content" of the memory address pointed by x
So, as other correctly pointed out, the function should be written as
void change_number(int *x)
{
*x = *x+3;
printf("In the subroutine: x = %d\n", *x);
}
Because as you act on *x you're acting on the content pointed by x
What is happening into main() ?
x is an int variable.
And you call:
change_number(&x);
The amplersand & means that you're not passing the value of x.
Instead you're passing a pointer to x, in other words the address in memory where the content of x is stored.
In other-other words x is passed by reference.
A final note: when writing a program in c (well, in any language, but expecially in c) the compiler warnings/errors and the debugger are your best friends.
Furthermore a good IDE will show you warnings as you type the code.
Anyway... the compiler should have warned you that
x = *x+3;
involves an implicit conversion from a int to int * (pointer to int) and most likely is a mistake.

You should use
*x = *x+3;
instead of
x = *x + 3;

What a function does with its parameters is, it makes a copy to work on and once the function's scope is ended, the copy is released which cannot change a value of a parameter passed to a function from outside.This is where pointers come in.
when passing a pointer to a function, think of it as a copy of the real address where in your case x is stored.
Thus in order to use x or change x, you have to use or change respectively *x(and it gets later dereferenced in the main program by &.
so like many others mentioned x = *x+3; should be *x = *x+3; and you'll get the desired results

Instead of printing in the change function you can also print in the main function by doing
*x=*x+3

Related

Why are the addresses of two variables in separate functions stored at the same address?

I have defined two functions foo1, foo2, and foo3 each function receives one argument (xval),(yval) and I also declared only one variable in each function (x),(y). why when printing x address, and y address. I find that the address is constant. And the same reason is given with xval, yval.
Here is the code:
#include <stdio.h>
void foo1(int xval) {
int x;
x = xval;
printf("X Address == 0x%x, Value of x == %d\n", &xval, x);
}
void foo2(int dummy) {
int y = dummy;
printf("Y Address == 0x%x, Value of y == %d\n", &dummy, y);
}
int main() {
foo1(7);
foo2(11);
return 0;
}
In foo1 and foo2 you are printing out the addresses of local variables (xval and dummy respectively) that are placed on the stack.
If I remember correctly, the C++ specification does not require these local variables to have different addresses. This should not concern you either.
The address of those variables has meaning only within the function in which the variable is defined, so comparing the addresses accross two different functions is meaningless.
What technically happens under the hood is, the compiler has placed 7 on the stack in your main() function before calling foo1(). Then foo1() prints out the address of that variable in the stack.
When foo1() is finished, the variable is popped from the stack and then 11 is placed on the stack before calling foo2(). This accidentally has used the same memory address but you should not count on this. For example, if you call foo2() from within foo1() this would affect the stack and the address would be different. Try the following:
#include <stdio.h>
extern void foo2(int dummy);
void foo1(int xval)
{
int x;
x = xval;
printf("X Address == 0x%x, Value of x == %d\n", &xval, x);
foo2(11);
}
void foo2(int dummy)
{
int y = dummy;
printf("Y Address == 0x%x, Value of y == %d\n", &dummy, y);
}
int main()
{
foo1(7);
return 0;
}
In summary, do not try to analyze what the concrete address value is. Simply use the address without looking into it. This is platform and compiler dependent.
xval and dummy are temporary variables. ("automatic variables" is the C term for them.) They're only guaranteed to exist while the function is executing. So there's no reason they couldn't be at the same address.
On your standard home computer, they would be found on the stack. Given they are both the first argument to the function, and given that the functions are called in sequence, I would be surprised if they didn't have the same address.
In fact, if you didn't take the address of the parameter, it's entirely possible for the argument to be passed to the function using a register so that no memory would be used at all.

What is the difference between referencing pointers in a function

I'm creating a function which modifies a variable so it can be used by the function referencing it (parent function?).
Is there a difference between using '&x' compared to using 'z' in the code below?
void changeX(int *p);
int main(void) {
int x = 10;
printf("%d\n",x);
int *z = &x;
changeX(z);
printf("%d\n",x);
// or
changeX(&x);
printf("%d\n",x);
return 0;
}
void changeX(int *p){
*p = *p + *p;
}
wildplasser made a good point, updated to show where I have gotten each value in the output.
Output is:
10
20
40
Both produce the same outcome (change x in the same way), but is there a non-obvious difference between them?
Thanks for the answers in the comments. It makes sense to me now.
The first call initializes the parameter from the argument z, i.e., the value of the argument is the value of the pointer z, which was initialized to be &x, a pointer value that points to the object x. The second call initializes the parameter from the argument &x, which is a pointer value that points to the object x. There is no functional difference between the two calls. In both cases, the parameter p in the function will have the exact same value, a pointer value that points to x, the only difference is where that value came from at the point where function was called…

Stack execution in C [duplicate]

This question already has answers here:
What will be the value of uninitialized variable? [duplicate]
(6 answers)
Closed 4 years ago.
For the following code
#include <stdio.h>
void f() {
int x;
printf("x = %d\n", x);
}
void g() {
int y = 42;
printf("y = %d\n", y);
}
int main() {
f();
g();
return 0;
}
I get the following output
x = 22031
y = 42
If I change the order of the last two functions being executed in main() and run the code
void f() {
int x;
printf("x = %d\n", x);
}
void g() {
int y = 42;
printf("y = %d\n", y);
}
int main() {
g();
f();
return 0;
}
I get the following :
y = 42
x = 42
Can someone explain this to me please.I know it has to do with the way memory is allocated in addresses but I am not sure about the details.
x = 22031
y = 42
The X value is uninitialized stack garbage values. When your program is loaded into RAM it does not zero out stack or heap memory. Here is a reference for a C programs memory model.
The interesting case is when
y = 42
x = 42
So what is going on here? Well when you call the g function first, you pop values onto the stack (growing down in the memory model, or up if the memory model is different). The next time you call the f function the values of the uninitialized stack garbage has changed, to be what was assigned when you called g (assigning y's address to 42). This is because you have the same number of parameters and local variables pushed onto the stack in both functions, if you tweak them you will see different values. For example the following g definition may cause x to print 43 instead, depending on how the local variables get popped onto the stack.
void g() {
volatile int z = 43;
int y = 42;
printf("y = %d\n", y);
}
Make the compiler doesnt optimize it out "z" if you want to mess around with this.
You are seeing uninitialized values in memory from "something else" i.e. undefined behavior. When you run your program, you are getting and seeing "old" values in memory which come from something else than your program in your computer.
For example, the following program will experience undefined behavior because x is read before it is initialized and the value of x comes from another process:
#include <stdio.h>
int main() {
int x;
printf("x = %d\n", x);
return 0;
}

understanding pointers in functions (referring values)

int func (int a, int b, int *c);
int main()
{
int res, x, y, z; //int res, x, y, *z;
printf("enter x \n");
scanf("%i", &x);
printf("enter y \n");
scanf("%i", &y);
res = func(x, y, &z); //res = func(x, y, z);
printf("result addition: %i, result multiplication %i \n", res, *z);
return 0;
}
int func (int a, int b, int *c)
{
int result;
result = a +b;
*c = a*b; //(1) alternative:d=a*b
// c=&d
return result;
}
My problem is, that i don't understand, why this code doesn't work when i write it as i like i did in the comments (//) . Compiler warns me, that z is not initialised, but why isn't that a problem in the working version?
Another thing i don't understand is, why it's correct to refer pointer a value like i did it in (1) but it's wrong in the following code:
int main()
{
int a, *c, *d;
scanf("%i", &a);
*c=a; //wrong
d=&a; //correct
return 0;
}
Compiler warns me, that z is not initialised, but why isn't that a problem in the working version?
The compiler warns you about z being uninitialized because you're passing it by value. And what you're passing is an uninitialized value (which is basically garbage).
It doesn't warn you when you pass the address of z because there's nothing wrong with passing the address of a variable to a pointer. The compiler doesn't check whether you're going to dereference c and use the uninitialized value of z. The compiler's just not that "smart". It assumes you'll do the right thing and just assign z a value by dereferencing c (which you indeed did).
why it's correct to refer pointer a value like i did it in (1) but it's wrong in the following code
As for your 2nd question, the first example works because the parameters of the functions get initialized to whatever values you called the function with.
The 2nd example doesn't work because you're using uninitialized local variables.
At the point where a variable is declared, it comes into existence at some memory location that can be retrieved with &, whereas (if you don't initialize it) the contents of that location is uninitialized. When z is an int, &z is a well-defined pointer because it is the address of a variable, not the contents of one. When z is an int *, z's content is itself a pointer, but it's not initialized; hence the warning (and most likely, your program will crash when scanf() attempts to write to an arbitrary memory location).
your question implies that you have no knowledge about pointers, I suggest you read about them first,
a pointer points to a variable, when you do
*c = a
you are trying to assign a value to the variable pointed to by c with the indirection operator '*',
the problem is that c is not pointing to anything in your code.
in the second one
d = &a;
you make the pointer d point to a. In other words you assign d the address of a. You really should read about pointers first otherwise, whatever we say here will not make sense to you.

C: "Invalid free(): Address 0x7feffee08 is on thread 1's stack"

This is not my exact code, but it is like this in essence. I'm trying to create a stack variable in main()
int **x;
that I want to pass to a function foo(int **x, arg1, arg2, ...). On some condition, I'm supposed to dynamically allocate space for x in foo()
x = (int **) malloc(sizeof(int *) * num_elems);
I am also not allocating new space for each int * element, but assigning to it &y, where int y was created in foo().
I got this error when I tried freeing x in main(). I don't understand what it means, but I suspect it might be because I used &y?
EDIT: Also relevant: I got garbage values when I tried accessing the double-dereferenced elements of x.
You are not correctly declared in main function and not correctly defined in foo() function. You have to declare as
In main function
int *x ;
foo(&x);
In foo(int **x,....)
*x = malloc(sizeof(int) * num_elems);
Consider this,
void foo()
{
int y;
int *x = NULL;
x = &y;
}
In this case, y is stored in the stack. When foo returns, y will be unavailable (implementation dependant). If you absolutely need to do this, malloc y instead. If you do that, y will be stored on the heap instead.

Resources