What would be the values after performing this operation?
#include <stdio.h>
int main() {
int *a = 0;
int *b = 3;
*a++ = *b++;
printf("%d", a);
printf("%d", b);
return 0;
}
The code above gives me a segmentation fault.
*a++ = *b++ (what does it mean, how it works)
*a++ = *b++;
means
*(a++) = *(b++);
x++ increments x and returns the original value. So the following is equivalent:
*a = *b; // Copy the `int` to which `b` points into the `int` to which `a` points.
a = a + 1; // Make `a` point to the following `int`.
b = b + 1; // Make `b` point to the following `int`.
Before: After:
a a
+----------+ +----------+ +----------+ +----------+
| ---------->| x | | ------+ | p |
+----------+ +----------+ +----------+ | +----------+
| y | +--->| y |
+----------+ +----------+
| | | |
b b
+----------+ +----------+ +----------+ +----------+
| ---------->| p | | ------+ | p |
+----------+ +----------+ +----------+ | +----------+
| q | +--->| q |
+----------+ +----------+
| | | |
The code above gives me a segmentation fault.
You assigned garbage to a and b. 0 as a pointer is the NULL pointer, and 3 isn't a valid pointer.
Given
#include <stdio.h>
int main() {
int *a = 0;
int *b = 3;
*a++ = *b++;
printf("%d", a);
printf("%d", b);
return 0;
}
the printed values can not be predicted as the code invokes undefined behavior in multiple ways.
First, both *a and *b invoke undefined behavior by dereferencing invalid pointers - a is initialized to a null pointer value, and b is initialized to point to address 3, which is almost certainly invalid also.
Second,printf("%d", a); invokes undefined behavior by trying to print an int * variable with the %d format specifier for int. The proper code would be
printf("%p", ( void * ) a);
It's not clear what the currently-posted code is supposed to do.
Related
I have the below program in C. How did p[0][0] become 1? Can somebody help in understanding?
#include <stdio.h>
#include<stdlib.h>
main()
{
int i,j;
int **p=(int **)malloc(2 * sizeof(int *));
p[0]=(int*) malloc(2*sizeof(int));
p[1]=p[0];
for(i=0;i<2;i++)
for(j=0;j<2;j++)
{
p[i][j]=i+j;
printf("%d,%d,%d",i,j,p[i][j]);
printf("\n");
}
printf("%d,%d,%d",i,j,p[0][0]);
}
the output is as below
0,0,0
0,1,1
1,0,1
1,1,2
2,2,1
The same pointer is assigned to p[0] and p[1]. This means p[0] and p[1] points at the same array. Therefore updates done via p[1] is also visible via p[0].
In the second iteration of outer for loop, 1 is assigned to p[1][0]. This makes p[0][0] to be 1.
After the following lines of code:
int **p=(int **)malloc(2 * sizeof(int *));
p[0]=(int*) malloc(2*sizeof(int));
p[1]=p[0];
this is what you have in memory:
int ** int * int
+---+ +---+ +---+
p: | | ------> | | p[0] -+-> | | p[0][0], p[1][0]
+---+ +---+ | +---+
| | p[1] -+ | | p[0][1], p[1][1]
+---+ +---+
p[0] and p[1] point to the same 2-element array, so anything you write to p[0][i] is reflected in p[1][i] and vice-versa.
What you probably meant to do was something like
int **p = malloc( 2 * sizeof *p ); // cast not necessary, sizeof *p == sizeof (int *)
p[0] = malloc( 2 * sizeof *p[0] );
p[1] = malloc( 2 * sizeof *p[1] );
which would give you
int ** int * int
+---+ +---+ +---+
p: | | ------> | | p[0] ----> | | p[0][0]
+---+ +---+ +---+
| | p[1] --+ | | p[0][1]
+---+ | +---+
|
| +---+
+-> | | p[1][0]
+---+
| | p[1][1]
+---+
I'm studying pointer in C language and I have some questions.
#include <stdio.h>
int main()
{
char c = 'A';
char* pc = &c;
char** ppc = &pc;
printf("%p %p\n", pc, ppc);
printf("%p %p\n", pc + 1, ppc + 1);
printf("%p %p\n", &c, &c + 1);
printf("%p %p\n", &pc, &ppc);
printf("%p %p\n", &pc + 1, &ppc + 1);
return 0;
}
In this code, let's say that
&c = 0117FE7B
&pc = 0117FE6C
&ppc = 0117FE60
I thought some answers will be like this:
ppc + 1 = 0117FE6D
&pc + 1 = 0117FE6D
&ppc + 1 = 0117FE61
but the correct answer was like this:
ppc + 1 = 0117FE70
&pc + 1 = 0117FE70
&ppc + 1 = 0117FE64
and I don't understand why. Can someone explain this for me?
(My computer is using 64 bit windows OS.)
Pointer arithmetic is done in terms objects, not bytes. If p evaluates to the address of a 4-byte int object, then p + 1 evaluates to the address of the next 4-byte int, not the next byte:
int x; // assume 4-byte int
int *ip = &x;
short s; // assume 2-byte short
short *sp = &s;
char c;
char *cp = &c;
+---+ +---+ +---+
x : | | <-- ip s : | | <-- sp c : | | <-- cp
+---+ +---+ +---+
| | | | | | <-- cp + 1
+---+ +---+ +---+
| | | | <-- sp + 1 | |
+---+ +---+ +---+
| | | | | |
+---+ +---+ +---+
| | <-- ip + 1 | | | |
+---+ +---+ +---+
| | | | | |
+---+ +---+ +---+
| | | | | |
+---+ +---+ +---+
| | | | | |
+---+ +---+ +---+
So depending on the size of the pointed-to type, p + 1 will either give the address + 1, or the address + 4, or the address + 8, etc.
Remember, the array subscript operation a[i] is defined as *(a + i) - given a starting address a, offset i objects (not bytes!!) from that address and deference the result.
Can you explain these outputs?
1)
char s[]="TvNnFs",*p;
for(p=&s[5];p>=s;p--)
--*p;
puts(s);
OUTPUT: SuMmEr
2)
char s[]="TvNnFs",*p;
for(p=&s[5]; p>=s; p--)
((--*p)<'a') ? (*p+=('a'-'A')) : (*p);
puts(s);
OUTPUT:summer
This
char s[]="TvNnFs",*p;
where s is an array of characters and p is character pointer, is looks like below
s[0] s[1] s[2] s[3] s[4] s[5] s[6]
------------------------------------------
| T | v | N | n | F | s | \0 |
------------------------------------------
s 0x100 0x101 0x102 0x103 0x104 0x105 0x106.. (assume 0x100 is base address of s)
Next, the for loop
for(p=&s[5];p>=s;p--)
--*p;
Here p=&s[5] the pointer p points to address of s[5] i.e 0x105. Next is p>=s i.e 0x105 >= 0x100 which is true, then --*p executes i.e first *p that means value at 0x105 memory location which is s and decrements on that will makes s[5] as r.
Now char array s looks like
s[0] s[1] s[2] s[3] s[4] s[5] s[6]
---------------------------------------------
| T | v | N | n | F | r(new)| \0 |
---------------------------------------------
s 0x100 0x101 0x102 0x103 0x104 0x105 0x106..
Note : you might interested to know that by doing --*p how does s got affected ? Its because p is pointing or holding the address of s i.e whatever changes are done on *p will affect indirectly to s.
After that p-- happens i.e p now points to one location previous than before i.e 0x104. Same operation will happens until p reach to s i.e 0x100 >= 0x100. Finally char array s looks like
s[0] s[1] s[2] s[3] s[4] s[5] s[6]
-------------------------------------------
| S | u | M | m | E | r | \0 |
-------------------------------------------
s 0x100 0x101 0x102 0x103 0x104 0x105 0x106..
Hence it prints SuMmEr.
Case 2 :
char s[]="TvNnFs",*p;
for(p=&s[5]; p>=s; p--)
((--*p)<'a')?(*p+=('a'-'A')):(*p);
puts(s);
Here
s[0] s[1] s[2] s[3] s[4] s[5] s[6]
------------------------------------------
| T | v | N | n | F | s | \0 |
------------------------------------------
s 0x100 0x101 0x102 0x103 0x104 0x105 0x106..
|
p points here
For 0x105 >= 0x100 : this
((--*p)<'a')?(*p+=('a'-'A')):(*p);
is ternary operator i.e first ((--*p)<'a') executes, if it results in true then (*p+=('a'-'A')) will be the output else (*p). So Here it looks like ((--*p)<'a') i.e 'r' < 'a' which is false so just (*p) but s[5] got changed after this due to --*p.
s[0] s[1] s[2] s[3] s[4] s[5] s[6]
------------------------------------------
| T | v | N | n | F | r | \0 |
------------------------------------------
s 0x100 0x101 0x102 0x103 0x104 0x105 0x106..
|
p points here due to p--
Next, For 0x104 >= 0x100 : this
((--*p)<'a')?(*p+=('a'-'A')):(*p);
'E' < 'a' i.e 70 < 97 which is true so this (*p+=('a'-'A')) gets execute i.e
*p = *p + ('a' - 'A')
= 'E' + (97 - 65)
= 'E' + 32
*p = 'e' /* now s[4] overwritten by e(previously F) */
Now array looks like
s[0] s[1] s[2] s[3] s[4] s[5] s[6]
------------------------------------------
| T | v | N | n | e | r | \0 |
------------------------------------------
s 0x100 0x101 0x102 0x103 0x104 0x105 0x106..
|
p points here due to p--
Same operation hoes on until 0x100 >= 0x100.
I am trying to pass a structure's array to a function, but it gives me an error when i becomes 1, acces violation.
Here is my code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <conio.h>
typedef struct {
int locuri;
int putere;
char marca[50];
char culoare[50];
int an_fabricatie;
}automob;
void aloca(automob **autos, int n)
{
*autos = (automob*)malloc(sizeof(automob)*n);
if (autos == NULL) {
exit(1);
}
}
void read_autos(const char* filename, automob **A, int *n)
{
FILE *f_in = fopen(filename, "r");
int i = 0, aux;
if (f_in == NULL) {
printf("Nu s-a gasit fisierul!");
_getch();
exit(0);
}
fscanf(f_in, "%d", n);
aloca(A, *n);
while (i < (*n)) {
fscanf(f_in, "%d", &A[i]->locuri);
fscanf(f_in, "%d", &A[i]->putere);
fscanf(f_in, "%s", &A[i]->marca);
fscanf(f_in, "%s", &A[i]->culoare);
fscanf(f_in, "%d", &A[i]->an_fabricatie);
i++;
}
}
void main()
{
int n;
automob *A;
read_autos("autos.in", &A, &n);
_getch();
}
I think the pointer A is not allocated properly but I really don't know. Do you have any ideas? Because this works when I write it in the main function but does not work if I right it in another function like read_autos.
A[i] -> locuri means (* A[i]).locuri; this would make sense if A was an array of pointers to automob; but it isn't. You want (* A)[i].locuri. And so on for the other fields.
fscanf(f_in, "%d", &(* A)[i].locuri);
fscanf(f_in, "%d", &(* A)[i].putere);
fscanf(f_in, "%s", (* A)[i].marca);
fscanf(f_in, "%s", (* A)[i].culoare);
fscanf(f_in, "%d", &(* A)[i].an_fabricatie);
What you wrote:
+------+ +-------+ +--------------------------------------------+
| A -----> | A[0] -----> | locuri | putere | marca | culoare | an_fab |
+------+ | | +--------------------------------------------+
+-------+ +--------------------------------------------+
| A[1] -----> | locuri | putere | marca | culoare | an_fab |
| | +--------------------------------------------+
+-------+ +--------------------------------------------+
| A[2] -----> | locuri | putere | marca | culoare | an_fab |
| | +--------------------------------------------+
+-------+ +--------------------------------------------+
| A[3] -----> | locuri | putere | marca | culoare | an_fab |
| | +--------------------------------------------+
+-------+
What you want:
+------+ +-------+ +--------------------------------------------+
| A -----> | * A -----> [0] | locuri | putere | marca | culoare | an_fab |
+------+ +-------+ +--------------------------------------------+
[1] | locuri | putere | marca | culoare | an_fab |
+--------------------------------------------+
[2] | locuri | putere | marca | culoare | an_fab |
+--------------------------------------------+
[3] | locuri | putere | marca | culoare | an_fab |
+--------------------------------------------+
(It is a comment but I do not have 50 reputation, so I answer and you could convert it as a comment)
When I have such problem and it happens, I do not hesitate to simply print pointer value.
For example, in your case :
printf("sizeof %I64u\n",sizeof(automob));
printf("Global Addr %I64u\n",*A);
printf("1st elt Addr %I64u\n",&(*A)[0]);
printf("2nd elt Addr %I64u\n",&(*A)[1]);
printf("1st elt / 1st field Addr %I64u\n",&(*A)[0].locuri);
printf("2nd elt / 2nd field Addr %I64u\n",&(*A)[1].locuri);
In the following code
#include <stdio.h>
int main() {
union a {
int i;
char ch[2];
};
union a u;
int b;
u.ch[0] = 3;
u.ch[1] = 2;
printf("%d,%d,%d\n", u.ch[0], u.ch[1], u.i);
return 0;
}
The output I get is
3,2,515
Can anyone explain me why the value of i is 515?
union a {
int i;
char ch[2];
};
union a u; /* initially it contains gargage data */
All members of the union shares the common memory. In above case total of 4 bytes gets allocated for u because in 4 bytes(MAX memory needed) you can store both i and ch.
ch[1] ch[0]
----------------------------------
| G | G | G | G | => G means garbage/junk data, because u didn't initialized
----------------------------------
u
MSB LSB
when statement u.ch[0] = 3; executed only ch[0] initialized.
ch[1] ch[0]
--------------------------------------
| G | G | G | 0000 0011 | => G means garbage/junk data, because u didn't initialized
--------------------------------------
u
MSB LSB
And when u.ch[1] = 2; executed next 1 bytes gets initialized as
ch[1] ch[0]
------------------------------------------
| G | G | 0000 0010 | 0000 0011 | => G means garbage/junk data, because u didn't initialized
------------------------------------------
u
MSB LSB
As you can see above out of 4 bytes only first 2 bytes got initialized, still remaining 2 bytes are uninitialised so when you are printing u.i, its undefined behaviour.
If you want expected result then initialize then union variable first as
union a u = { 0 }; /* all 4 bytes got initialized at first instance itself, no chance of any junk data */
u.ch[0] = 3;
u.ch[1] = 2;
Now when you prints u.i, it prints data in whole 4 bytes which is 512 + 3 = 515 (In case of little enidian processor)