Passing Pointers to Functions in C [duplicate] - c

This question already has an answer here:
Confusion about the fact that uninitialized pointer points to anywhere
(1 answer)
Closed 4 years ago.
I'm going to take data structures course this year, so I decided to renew my knowledge about C by doing some simple tasks about pointers in C, and I have noticed one thing about passing pointers to functions, that I can't really understand.
Let's say we have a function:
void assignValueTen(int *var){
*var=10;
}
We can call this function from main like this:
int main( void ){
int x;
assignValueTen(&x);
printf("The value of x is %d.\n",x);
return 0;
}
The output of this would be:
The value of x is 10.
We can also call this function like this:
int main( void ){
int x, *y;
y=&x;
assignValueTen(y);
printf("The value of x is %d.\n",x);
return 0;
}
The output of this would also be:
The value of x is 10.
However, the statement below does not work as expected:
int main( void ){
int *x;
assignValueTen(x);
printf("The value of x is %d.\n",*x);
return 0;
}
Output of the code above is:
Process exited after 6.723 seconds with return value 3221225477
So, why does the code compile but not work as expected?
Is it because the pointer is not yet assigned to any address before in the last example?
Can somebody explain why this is happening in a little more detail?
Thanks a lot!

The one that does not work is because x is not assigned any value in particular. The assignment in the function is assigning wherever that uninitialized variable happens to point and that is very unlikely to be a valid address (as the hardware sees things) and even if it is valid (again according to the hardware) it is not somewhere you should be writing to (because the address would 'belong' to something other than the code you are running in main).
You should only access addresses you have reason to know are valid (your assignValueTen function has such as an implicit requirement), C does not really have a way to enforce such requirement contracts though some other languages do.

Because when you do:
int main( void ){
int x;
assignValueTen(&x);
printf("The value of x is %d.\n",x);
return 0;
}
or:
int main( void ){
int x, *y;
y=&x;
assignValueTen(y);
printf("The value of x is %d.\n",x);
return 0;
}
you're always printing an int , while in the last example you're trying to print a pointer to an int, or at least that's the way i see it.

Related

If a variable is defined previously and is waiting on a function to return a value, what is the value of that variable?

This is for programming in C.
Say I had the follow code in my program:
int fun1(int x);
int main (void)
{
int a = 5;
a = fun1(10);
}
int fun1(int x)
{
\\Program arbitrarily ends here
return x;
}
In my memory diagram what would the value of a be assuming the program terminates before fun1 is able to return a value? Would the value of a be undetermined (??) or would it be 5?
The value of a is already initialized to 5. Now, according to the condition, you want to know the results of that circumstance when the fun1() ends before it could return a value; assume the following:
int fun1(int x)
{
// return x;
}
Here we've supposed the function quits before returning the value.
You'll still get the output 5 before, during or after execution of the program since it returns nothing but the variable a is preassigned to 5 and it can't be changed to 10 unless the function returns 10 and assigns to the variable.
But remember, if you don't assign anything to a, then it may show an unexpected value (I got 4195638 when used printf() for a).

Trouble in C program for getting output [duplicate]

This question already has answers here:
Parameter Passing in C - Pointers, Addresses, Aliases
(2 answers)
Closed 4 years ago.
This is a simple program
#include<stdio.h>
void get(int,int);
void main()
{
int a,b;
get(a,b);
printf("In main");
printf("%d",a);
}
void get(int m,int n)
{
printf("enter the value");
scanf("%d%d",&m,&n);
}
and I got an output is
enter the value
4
5
in main:
0
Why is the value of m in get() not assigned to a in main()? What's my mistake?
You're passing your main variables via value. Read about how you can pass by reference, here. scanf requires addresses of variables in order to modify them; so you need to pass their addresses like this:
get(&a, &b);
And you can modify your get() method like this:
void get(int* pM,int* pN) {
printf("enter the value");
scanf("%d%d, pM, pN);
}
Your scanf reads into function local variables which store the values you give as parameters to the function.
Their values are not visible in the variables you give as parameters to the function.
You probably want to use pointers to variables as parameters, then the read values can end up in the variables pointed to by those pointer-parameters.
This is basically happening due to scope of variables, since integers are passed by value and not by reference.
You need to return values of a and b for them to be present in main().
see more here
https://www.tutorialspoint.com/cprogramming/c_function_call_by_value.htm
#inlcude<stdio.h>
int get(int,int);
void main() {
int a,b;
a = get(a,b);
printf("In main");
printf("%d",a);
}
int get(int m,int n){
printf("enter the value");
scanf("%d%d,&m,&n);
return m;
}
Enter the value
10 20
In main
10
Also, read about indenting the code so that it's more readable.
Why is the value of m in get() not assigned to a in main()? What's my mistake?
First, you need to understand the concept of parameter passing in C.
[If you are not aware of formal and actual parameters, check this]
Technically, everything in C is pass-by-value. Here,
get(a,b);
you are passing the value of a and b variable to function get(). The value of actual parameter a and b will be copied to formal parameters m and n [in this case, the value of a and b variable is garbage since you have not initialized them]. Any modification to the value of formal parameters (m and n) in the calling function will not reflect in the actual parameters (a and b) because formal parameter storage is separate. Hence, the value of m in get() does not assigned to a in main().
Below part of the answer is based on the assumption that you are aware of the concept of pointers in C language. If not, I would suggest to pick choose a good C language book/tutorial and go through the concept of pointers.
C language provides a facility to pass a pointer to a function which is also pass-by-value only. It copies the value of the pointer, i.e. the address, to the function formal parameters and you can access the value stored at that address by dereferencing the pointer. Hence, any changes made in the value at the address passed will reflect in the calling function actual parameters.
So, you can do:
#include<stdio.h>
void get(int *, int *);
int main()
{
int a, b;
get(&a, &b);
printf("In main\n");
printf("a : %d, b = %d\n", a, b);
}
void get(int *m,int *n)
{
printf("Enter the value:\n");
scanf("%d%d", m, n); // m holds the address of a and n holds the address of b variable.
printf("Value entered:\n");
printf("%d %d\n", *m, *n); //dereferencing the pointer m and n
}

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.

pointers for getting elements of an array in C [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
pointer arithmetic in C for getting a string
I am a newbie in C and I would like to get the elements of an array with a function, I have tried different options, but I still do not get the elements.
My function is:
void getelements(int *a, int cl)
{
int *p;
for (p=&a[0];p<&a[cl];p++)
{
printf("%d\n",*p);
}
}
I know that the solution should work like that, but it only prints the first element and then memory positions. I am calling my function with:
int v={10,12,20,34,45};
getelements(&v,5);
Any help? I need to use arithmetic of pointers.
Thanks
First, Please don't update code to fix bugs while a question is open. It makes most of the current answers meaningless, doesn't grant credit where it is due to the person(s) that solved one or more issues in your prior code, and makes the casual reader looking for a related problem to their own completely confused by both the question and the answers therein. If you want to amend an update do so in addition to the original problem, but if it an entirely different issue, then mark as answered, give credit where it is due, and open a new question with your new code and different problem(s) (ideally, anyway).
As written now, your function is fine. But your real issue is this:
// compile with -Wall -Werror and look at the warning here
int v={10,12,20,34,45}; // <== WRONG
getelements(&v,5); // <== Harmless, but bad form.
This should be like this instead, assuming you want to print all elements in the array:
int v[] = {10,12,20,34,45};
getelements(v, sizeof(v)/sizeof(v[0]));
Note the [] following your array. Without it, the &v was masking what would have been a big-fat warning or error from the compiler that int is being passed as an int *. Furthermore, if you compile your prior code with full warnings treated as errors (-Wall -Werror for gcc) you will get an error like the following on your v declaration line:
main.c:116:15: Excess elements in scalar initializer
In other words, everything past the first element was ignored, and thus your pointer was running off into undefined behavior land. Changing the declaration and invocation to what I have above will address this as well as ensure you don't make that mistake again, since sizeof(v[0]) won't even compile unless v is an array or pointer type. The latter can still cause headaches when you use a pointer rather than an array with such a calculation, but thats something you just have to discipline yourself against doing in C.
try this and let me know if that works.
void getelements(int *a)
{
int *p;
int l=5;
for (p=a;p<a+l;p++)
{
printf("%d\n",*p);
}
}
It's best to pass in the length of the array along with the array itself.
#include <stdlib.h>
#include <stdio.h>
void get_elements(int* values, int length)
{
int i;
for (i = 0; i < length; ++i)
{
printf("%d\n", values[i]);
}
}
int main(int argc, char** argv)
{
int vals[3];
vals[0] = 0;
vals[1] = 1;
vals[2] = 2;
get_elements(vals, 3);
getchar();
return 0;
}
Using the code similar to your original post (before the addition of the array length as a method parameter), you could do the follow (which is a bit convoluted if you ask me).
void get_elements(int* values, int length)
{
int *p;
for (p = &values[0]; p < &values[length]; p++)
{
printf("%d\n", *p);
}
}
Actually you are passing array address in
getelements(&v,5)
in function
getelements()
you are treating it like an array!!!
void getelements(int *a, int cl)
{
int *p;
for (p=a;p<a+cl;p++)
{
printf("%d\n",*p);
}
}
Let me know if you are cleared conceptually!!!
As per my knowledge and seeing your code.you have hardcoded the length of array to 5. I think you can also pass array length as a parameter to function; or you can use this function and see if it gives the desired result
void getelements(int *a)
{
int *p;
int i = 0;
int l=5;
p = a
for (i = 0;i<l;i++)
{
printf("%d\n",*(p + i));
}
}

What is wrong with this C code

I have a piece of code where I am trying to return the square of the value pointed to by *ptr.
int square(volatile int *ptr)
{
int a,b;
a = *ptr;
b = *ptr;
return a * b;
}
main()
{
int a=8,t;
t=square(&a);
printf("%d",t);
}
Its working fine for me but author of this code said it might not work because of following reason:
Because it's possible for the value of *ptr to change unexpectedly, it is possible for a and b to be different. Consequently, this code could return a number that is not a square!. The correct way to do is
long square(volatile int *ptr)
{
int a;
a = *ptr;
return a * a;
}
I really wanted to know why he said like that?
The idea of the volatile keyword is exactly to indicate to the compiler that a variable marked as such can change in unexpected ways during the program execution.
However, that does not make it a source of "random numbers" - it just advises the compiler - what is responsible for actually changing the variable contents should be another process, thread, some hardware interrupt - anything that would write to the process memory but not inlined in the function where the volatile declaration finds itself. In "older times" (compilers with less magic) everything it did was preventing the compiler from caching the variable value in one of the CPU registers. I have no idea on the optimisations/de-optimistions strategies triggered by it by modern compilers - but it will at least do that.
In the absense of any such external factor, a "volatile" variable is just like any other. Actually - it is just like any other variable - as variables not marked as volatile can also be changed by the same external causes (but the compiled C code would not be prepared for that in this case, which might lead to incorrect values being used).
Since the question has an accepted and correct answer, I will be brief: here is a short program that you can run to see the incorrect behavior happening for yourself.
#include <pthread.h>
#include <math.h>
#include <stdio.h>
int square(volatile int *p) {
int a = *p;
int b = *p;
return a*b;
}
volatile int done;
void* call_square(void* ptr) {
int *p = (int*)ptr;
int i = 0;
while (++i != 2000000000) {
int res = square(p);
int root = sqrt(res);
if (root*root != res) {
printf("square() returned %d after %d successful calls\n", res, i);
break;
}
}
done = 1;
}
int main() {
pthread_t thread;
int num = 0, i = 0;
done = 0;
int ret = pthread_create(&thread, NULL, call_square, (void*)&num);
while (!done) {
num = i++;
i %= 100;
}
return 0;
}
The main() function spawns a thread, and modifies the data being squared in a loop concurrently with another loop calling the square with a volatile pointer. Relatively speaking, it does not fail often, but it does so very reliably in less than a second:
square() returned 1353 after 5705 successful calls <<== 1353 = 33*41
square() returned 340 after 314 successful calls <<== 340 = 17*20
square() returned 1023 after 5566 successful calls <<== 1023 = 31*33
First understand what's volatile: Why is volatile needed in C?
and then, try to find answer by yourself.
It's a game of volatile and hardware world. :-)
Read answer given by Chris Jester-Young:
volatile tells the compiler that your variable may be changed by other means, than the code that is accessing it. e.g., it may be a I/O-mapped memory location. If this is not specified in such cases, some variable accesses can be optimised, e.g., its contents can be held in a register, and the memory location not read back in again.
If there is more than one thread, the value the pointer points to might change inbetween statement "a = *ptr" and statement "b = *ptr". Also: you want the square of a value, why put it into two variables?
In the code you present then there is no way for the variable a that is defined in your main to be modified whilst square is running.
However, consider a multi-threaded program. Suppose that another thread modified the value to your your pointer refers. And suppose that this modification took place after you had assigned a, but before you had assigned b, in the function sqaure.
int square(volatile int *ptr)
{
int a,b;
a = *ptr;
//the other thread writes to *ptr now
b = *ptr;
return a * b;
}
In this scenario, a and b would have different values.
The author is correct (if *ptr will be changed by other threads)
int square(volatile int *ptr)
{
int a,b;
a = *ptr;
//between this two assignments *ptr can change. So it is dangerous to do so. His way is safer
b = *ptr;
return a * b;
}
Because the value of the pointer *ptr might change between the first affection and the second one.
I don't think the value of *ptr can change in this code barring an extremely unusual (and non-standards-compliant) runtime environment.
We're looking at the entirety of main() here and it's not starting up other threads. The variable a, whose address we are taking, is a local in main(), and main() doesn't inform any other function of that variable's address.
If you added the line mysterious_external_function(&a); before the t=square(&a) line, then yes, mysterious_external_function could start a thread and diddle the a variable asynchronously. But there's no such line, so as written square() always returns a square.
(Was the OP a troll post, by the way?)
I see some answers with *ptr can be changed by other threads. But this cannot happen since *ptr is not a static data variable. Its a parameter variable and local and parameter variables being hold inside stack. Each thread has its own stack section and if *ptr has been changed by another thread, it should not effect the current thread's.
One reason why the result might not give the square can be an HW interrupt might happen before assigning b = *ptr; operation as indicated below:
int square(volatile int *ptr) {
int a,b;
a = *ptr; //assuming a is being kept inside CPU registers.
//an HW interrupt might occur here and change the value inside the register which keeps the value of integer "a"
b = *ptr;
return a * b;
}

Resources