one address have two values? - c

The following code shows me that for one address I have two values. For an example:
Address is: 0xbfcca1ac <br>
Value is: 5
Address is: 0xbfcca1ac <br>
Value is: -1077108308
What am i doing wrong?
#include <stdio.h>
void Input(int *A, int n) {
int i, x=5;
for(i=0; i<n*n; i++) {
*(A+i) = x;
}
printf("\n\n\n\nAddress is: %p\n", A);
printf("Value is: %d\n", *A);
}
main() {
int A[3][3], i, j, n=3;
Input(A, n);
printf("\nAddress is: %p\n", A);
printf("Value is: %d", *A);
return 0;
}

In your main(), A is a 2D array, so *A is an array of 3 integers. Printing *A using the %d format gives undefined behaviour, since *A is not an int.
In your Input(), A is a pointer to an int, so its value is treated as the address of anint. *A is then the value of an int, which is assumed to be at that address.
The value that main() passes to Input() will the address of A[0]. That has type "pointer to array of 3 int", but will happen to have the value equal to (in main()) &A[0][0].
Compilers will (if configured right) give warnings about your code, since it is passing values to functions of different types that those functions will expect. Since there is (at minimum) potential for undefined behaviour due to mismatch of types (function expecting a parameter of one type, but being given another), you should really not ignore such warnings. Even if you are somehow able to reason through what is happening.

You just make an error in the main when printing the value. Since A is a pointer to a pointer to int you should have: printf("Value is: %d",**A); (double dereference).
You compiler should have warned you for incompatible types when passing arguments, a cast will make your compiler silent: Input((int *)A,n);.
Also use the right prototype for main...

Try this :
#include <stdio.h>
typedef int int_of_three[3];
//Another way of saying int_of_three is int[3]
void Input(int_of_three A[3], int n) //int_of_three *A should also be fine
//provided you play by the limits.
{
int i, x=5;
for(i=0; i<n*n; i++)
{
*(*(A+i)) = x;
}
printf("\n\n\n\nAddress is: %p\n", *A);
// *A decays to another pointer.
printf("Value is: %d\n", **A);
printf("\nAddress is: %p\n", *(A+1));
printf("Value is: %d", *(*(A+1)));
}
main()
{
int_of_three A[3];
int n=3;
Input(A, n);
printf("\nAddress is: %p\n", *A);
printf("Value is: %d", **A);
printf("\nAddress is: %p\n", *(A+1));
printf("Value is: %d", *(*(A+1)));
return 0;
}

Related

Unexpected value by using printf (Call by reference in C)

#include <stdio.h>
int main()
{
int num1;
int *p;
p=&num1;
printf("Give a value\n");
scanf("%d", &num1);
printf("\n%d", num1);
f2(&num1);
printf("%d", *p);
return 0;
}
void f2(int *p)
{
*p *= *p;
}
A call by reference program just to return the square of a value
Well, the problem is that if I do not use printf the expected output is correct (e.g. 2*2=4)
However, if I include:
printf("\n%d", num1);
and run the programm I will take a non expected value (e.g. 2*2=24)
These two calls of printf result of outputting two values in the same line without a space.
printf("\n%d", num1);
f2(&num1);
printf("%d", *p);
If you want to make the output less confusing then for example write
printf("\n%d", num1);
f2(&num1);
printf("\n%d\n", *p);
There are two problems in your code.
You need to declare void f2(int* p) before using it. Depending on your platform you might get away with it. But a sane compiler should give you at least a warning (which should be considered as an error).
Sloppy format strings in your printfs make the output look wrong.
Try this:
#include <stdio.h>
void f2(int* p); // you need to declare this, otherwise you'll get a
// warning you should always conside as an error
int main()
{
int num1;
int* p;
p = &num1;
printf("Give a value\n");
scanf("%d", &num1);
printf("\nnum1 = %d\n", num1); // format string more explicit
f2(&num1); // warnig here if f2 is not declared as above
printf("*p = %d\n", *p); // format string more explicit
return 0;
}
void f2(int* p)
{
*p *= *p;
}
There are several problems with this code.
You need to either:
a. declare a prototype for f2. You can do this by putting the following code before your main
void f2(int *p);
b. put the entire f2 function before main (and this is the route that I'd probably choose - but questions of style are the cause of countless pointless wars.
The output is unclear. By not putting \n in your printf statement you're running the output of the two print statements together. Use this instead:
printf("\n%d\n", num1);
Pretty printing greatly improves readability. And don't be afraid of giving functions meaningful names.
On balance, I think I'd write your code like so:
#include <stdio.h>
void square(int *p) {
*p *= *p;
}
int main(int argc, char *argv[]) {
int num1;
int *p;
p = &num1;
printf("Give a value: ");
scanf("%d", &num1);
printf("\n%d squared is equal to: ", num1);
square(&num1);
printf("%d\n", *p);
return 0;
}
#include <stdio.h>
#include <math.h>
void f2 (int *p)
{
*p = pow(*p, 2); // equal with *p *= *p;
}
int main ()
{
int num1;
int *p; // p is pointer variable that points to num1
// type of num1 and p must be the same (int).
p = &num1; // p is address of num1
printf ("Give a value: ");
scanf ("%d", p); // p is address of num1
printf ("\nnum1 before: %d", *p); // *p is num1 (content of p)
f2 (p);
printf ("\nnum1 after: %d", *p); // missing \n in here
return 0;
}

Assigning int* to an int[] does not work as expected in dev c++

The following C code assigns a pointer to an array:
#include <stdio.h>
// ders 5 : Diziler vs. Isaretciler
int main(){
int array[20];
int i;
int* pointer = (int* )array;
// Fill the array with numbers from 0 to 20
for (i=1; i<=20; i++){
array[i] = i;
}
printf("5th element of the array: %d \n", array[4]);
printf("array: %d pointer: %d \n",array,pointer);
printf("The value pointed with (pointer+4) %d \n", *(pointer+4));
}
That "pointer" must be equal to the "array" by value, but it is not. So it gives an error and collapses. I work with BloodShed Dev C++ IDE (but the program is in C).
for (i=1; i<=20; i++){
C (and many other languages) starts index with zero. It shoule be the follows:
for (i=0; i<20; i++){
About the concept:
Array is not pointer. It decays into pointer in particular context, and the decayed value is the address of the first element of the array.
You don;t need to explicitly cast int* pointer = (int* )array; as int* pointer = array; itself returns the address of the first element which is same as the base address of the array.
Since you have declared the pointer to be int you can increment the pointer to access the next array value.
Also, in C the indexes start from zero so better having a loop starting from
for (i=0; i<20; i++){ which is the problem of your application crash. As C does not have boundary check and will call the value which is beyond the value allocated, it will throw a segmentation fault.
Try this
#include <stdio.h>
int main(){
int array[21];
int i;
int* pointer = array;
// Fill the array with numbers from 0 to 20
for (i=0; i<=20; i++){
array[i] = i;
}
printf("5th element of the array: %d \n", array[4]);
printf("array: %d pointer: %d \n",*array,*pointer);
printf("The value pointed with (pointer+4) %d \n", *(pointer+4));
}

Assigning values to initialized pointers

When we declare a pointer, we usually initialize it to a variable (memory mapping) and then assign a value to it.
#include <stdio.h>
int i=0;
int cir_shift(int *x,int *y);
int main()
{
int a,b,c,*temp,*d;
d=&c;
scanf("%d %d %d",&a,&b,&c);
temp=(d+3);
*temp=c;
cir_shift(d,temp);
printf("%d %d %d",a,b,c);
}
int cir_shift(int *x,int *y)
{
*x=*(x+1);
i++;
if(i==3)
{
return 0;
}
else
{
x++;
cir_shift(x,y);
}
}
Here, when I want to print the value of temp (*temp), it keeps crashing. I did initialize 'temp' to a memory address, but still it crashes. And, when I want to print the memory address stored at temp, it prints the value at temp (*temp). What seems to be the problem and what may the solution be? Thank you.
temp=(d+3);
*temp=c;
d + 3 means 3 int after where d is pointing to. It is an invalid address as you didn't allocate anything there. So then trying to write to *temp unleashes the infinite revenge of your implementation.
You should explain what you are trying to achieve with temp=(d+3);?

How to read variadic function parameters?

This is my code:
#include <stdio.h>
void add(int num, ...);
int main(void)
{
int a=100, b=200, c=300;
add(1, a);
add(2, a, b);
add(3, a, b, c);
return 0;
}
void add(int num, ...)
{
int *p=NULL;
p=&num+1;
printf("%x \n", p);
if(num==1)
{
printf("%d \n", p[0]);
printf("num is: %d \n", num);
}
else if (num==2)
{
printf("%d \n", p[0]+p[1]);
printf("num is: %d \n", num);
}
else
{
printf("%d \n", p[0]+p[1]+p[2]);
printf("num is: %d \n", num);
}
}
From my understanding, p initially points to a, which is 10. Thus, it should print 10, 30, 60, respectively. Nonetheless, it prints
6786db50
1736891264
num is: 1
6786db50
1736924031
num is: 2
6786db50
1867401241
num is: 3
Is p pointing to a wrong address? How can I correctly read the arguments passed as ...?
That's not how you use variadic function calls, you need to use the va_* function calls to extract the parameters.
See http://unixhelp.ed.ac.uk/CGI/man-cgi?stdarg+3 or http://en.wikipedia.org/wiki/Variadic_function#Variadic_functions_in_C.2C_Objective-C.2C_C.2B.2B.2C_and_D
Your particular example may or may not work (Works as you expected on my system). You do p=&num+1; to access the next element. This holds good under the assumption that the stack is ascending which may not be the case with your architecture. And on many systems, variables upto some limit, are passed on registers than on stack! So your assumption goes wrong totally. Also note the variables can be pushed on to the stack either from left to right or the other way. It is unspecified by the standard.
Hence you shouldn't work on assumptions and instead use functions designed for this particular use.

Arrays of pointers in C

Hii ,
I have written the following code to improve it for the higher datastructures .
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
int display(int *a , int *b , int *c)
{
a[0] = b;
a[1] = c;
printf("\n%d %d",a[0],a[1]); ------- point 1
printf("\n %d %d",*(a[0]),*(a[1])); ------- point 2
return 1;
}
int main()
{
int *a[5];
int b,c;
scanf("%d %d",&b,&c);
printf("%d %d",b,c);
display(a,&b,&c);
getchar();
}
I get the addresses in point 1 , but i dont get the values in point 2....What have i done wrong ... If my program itself is wrong , please jus give me a sample code that can dereference an array of pointers to get the value pointed by the element of array...
This code shouldn't compile. The signature for display should be int display(int **a , int *b , int *c), because a is a pointer to int* (remember that arrays degrade to pointers). Then, you need to write printf("\n%d %d",*a[0],*a[1]) to dereference the pointers in the array.
#include <stdio.h>
int display(int** a, int* b, int* c)
{
// store the value of b and c on array a
a[0] = b;
a[1] = c;
//print the memory addresses stored in hex format
printf("0x%x 0x%x\n", (int)a[0], (int)a[1]);
//print the values
printf("%d %d\n", *a[0], *a[1]);
return 1;
}
int main()
{
int* a[5];
int b,c;
scanf("%d %d",&b,&c);
printf("%d %d\n",b,c);
display(a,&b,&c);
getchar();
return 0;
}
The signature of display() indicates that a is a pointer. In theory, this might work in C, but gcc gave me an error. What you want to tell the compiler is that you want an array of pointers. I accomplished this with int **a in the function signature. The code below shows how I did this. Also, I cleaned it up a bit, since some of your includes aren't needed, the pointers should be printed as unsigned, display would probably be better as a void, having the "\n" at the beginning of the line was irritating in that the last line of output ended up on my prompt line, and the getchar() serves no real purpose here.
#include<stdio.h>
void display(int **a , int *b , int *c)
{
a[0] = b;
a[1] = c;
printf("%u %u\n", a[0], a[1]);
printf("%d %d\n", *a[0], *a[1]);
}
int main(void)
{
int *a[5];
int b,c;
printf("Enter two integers: ");
scanf("%d %d",&b,&c);
printf("%d %d\n",b,c);
display(a,&b,&c);
}
You want store addresses (pointers) in the vector a. Define your function to accept a vector of pointers:
int display(int *a , int *b , int *c)
This has the advantage that the compiler compiles the code.
Or better: use names that help to remember what you mean.

Resources