SE250:lab-2:ssre005
Started off having trouble finding Emacs, compiling a code and finding MS Word.
#include <stdio.h> int main (void) { int *ip; printf("%d\n", sizeof(ip)); return 0; }
The above code failed to compile as the pointer ‘ip’ was not set to any variable. As explained by the tutor, if the pointer is not set to point at the address of an existing value, it will point at a random address in memory and thus the compiler refuses to compile to code.
Thus, the following code was devised:
#include <stdio.h> int main (void) { int x = 10; int *ip = &x; printf("%d\n", sizeof(ip)); return 0; }
Problems with compiling still persisted but after changing the setup of emacs, the problem was solved and the value for the size of a pointer of type int returned was 4.
To answer the question: “Are all pointers the same size? What other data types in C are the same size?” the pointer’s type was changed to various others to see if the size output given was still 4(windows and linux).
Double – 4; lab2.c:6: warning: initialization from incompatible pointer type
Long – 4; lab2.c:6: warning: initialization from incompatible pointer type
Short – 4; lab2.c:6: warning: initialization from incompatible pointer type
Char – 4; lab2.c:6: warning: initialization from incompatible pointer type
Float – 4; lab2.c:6: warning: initialization from incompatible pointer type
Another student pointed out that you do not need to have a pointer pointing to a specific address for a size value to be returned. My earlier problems with compiling were actually caused by not using the correct commands in the command line of emacs.
#include <stdio.h> int main (void) { // int x = 10; double *ip;//= &x; printf("%d\n", sizeof(ip)); return 0; }
With the unnecessary lines commented out, the code was run again to produce exactly the same results without the warnings. (Same results with linux).
2.
#include <stdio.h> int main (void) { int x; int y; printf("&x = %p, &y = %p, diff = %ld\n", &x, &y, (long)(&x − &y)); return 0; }
Returned: &x = 0x22ccc4, &y = 0x22ccc0, diff = 1 (Windows)
&x = 0xfff3275c, &y = 0xfff32758, diff = 1 (Iinux)
Replacing the line “(long)(&x - &y)” with (long)&x - (long)&y returns the output:
&x = 0x22ccc4, &y = 0x22ccc0, diff = 4 (Windows)
&x = 0xfff3275c, &y = 0xfff32758, diff = 4 (Iinux)
3.
#include <stdio.h> int main (void) { int x; char arr[ 4 ]; int y; printf("&x = %p, &y = %p, diff = %ld\n", &x, &y, (long)&x - (long)&y); printf("Address of arr is %p. Value of &arr is %p. The value of arr+4 is %c. The value of &arr[4] is %p", &arr, &arr, arr + 4, &arr[4]); return 0; }
Returned: Windows:
&x = 0x22ccc4, &y = 0x22ccbc, diff = 8
Address of arr is 0x22ccc0. Value of &arr is 0x22ccc0. The value of arr+4 is Ä. The value of &arr[4] is 0x22ccc4
Linux: &x = 0xffd6075c, &y = 0xffd60754, diff = 8
Address of arr is 0xffd60758. Value of &arr is 0xffd60758. The value of arr+4
is \. The value of &arr[4] is 0xffd6075c
Varying the size of the array from 0 to 10 produced the following results:
For arr[0]:
&x = 0x22ccbc, &y = 0x22cc9c, diff = 32
Diff = 4 (linux)
For arr[1]:
&x = 0x22ccc4, &y = 0x22ccbc, diff = 8
Diff = 4 (linux)
For arr[2]:
&x = 0x22ccc4, &y = 0x22ccbc, diff = 8
Diff = 4 (linux)
For arr[3]:
&x = 0x22ccbc, &y = 0x22cc9c, diff = 32
Diff = 4 (linux)
For arr[4]:
&x = 0x22ccc4, &y = 0x22ccbc, diff = 8
Diff = 8 (linux)
For arr[5]:
&x = 0x22ccbc, &y = 0x22cc9c, diff = 32
Diff = 4 (linux)
For arr[6]:
&x = 0x22ccbc, &y = 0x22cc9c, diff = 32
Diff = 4 (linux)
For arr[7]:
&x = 0x22ccbc, &y = 0x22cc9c, diff = 32
Diff = 4 (linux)
For arr[8]:
&x = 0x22ccc4, &y = 0x22ccb4, diff = 16
Diff = 4 (linux)
For arr[9]:
&x = 0x22ccbc, &y = 0x22cc9c, diff = 32
Diff = 4 (linux)
For arr[10]:
&x = 0x22ccbc, &y = 0x22cc9c, diff = 32
Diff = 4 (linux)
Reverting the array to size 4, setting x and y to 0 and arr[4] to 10 and printing out the values of x and y with the following code:
#include <stdio.h> int main (void) { int x; char arr[ 4 ] = “10”; int y; printf("&x = %p, &y = %p, diff = %ld\n", &x, &y, (long)&x - (long)&y); printf("Address of arr is %p. Value of &arr is %p. The value of arr+4 is %c. The value of &arr[4] is %p", &arr, &arr, arr + 4, &arr[4]); return 0; }
Produced the output:
Windows:
&x = 0x22ccc4, &y = 0x22ccbc, diff = 8
Address of arr is 0x22ccc0. Value of &arr is 0x22ccc0. The value of arr+4 is Ä. The value of &arr[4] is 0x22ccc4
x = 0, y = 0
Linux:
&x = 0xff88e75c, &y = 0xff88e754, diff = 8
Address of arr is 0xff88e758. Value of &arr is 0xff88e758. The value of arr+4
is \. The value of &arr[4] is 0xff88e75c
4. x and y declared as global variables and the last 2 exercises repeated.
#include <stdio.h> int x = 0; int y = 0; int main (void) { char arr[4] = "10"; printf("&x = %p, &y = %p, diff = %ld\n", &x, &y, (long)&x - (long)&y); return 0; }
arr[0]:
Windows : &x = 0x403030, &y = 0x403020, diff = 16
Linux: &x = 0x10010a64, &y = 0x10010a68, diff = -4
arr[1]:
Windows: &x = 0x403030, &y = 0x403020, diff = 16
Linux: &x = 0x10010a64, &y = 0x10010a68, diff = -4
arr[2]:
&x = 0x403030, &y = 0x403020, diff = 16
Linux: &x = 0x10010a64, &y = 0x10010a68, diff = -4
arr[3]:
&x = 0x403030, &y = 0x403020, diff = 16
Linux: &x = 0x10010a64, &y = 0x10010a68, diff = -4
arr[4]:
&x = 0x403030, &y = 0x403020, diff = 16
Linux: &x = 0x10010a64, &y = 0x10010a68, diff = -4
arr[5]:
&x = 0x403030, &y = 0x403020, diff = 16
Linux: &x = 0x10010a64, &y = 0x10010a68, diff = -4
arr[6]:
&x = 0x403030, &y = 0x403020, diff = 16
Linux: &x = 0x10010a64, &y = 0x10010a68, diff = -4
arr[7]:
&x = 0x403030, &y = 0x403020, diff = 16
Linux: &x = 0x10010a64, &y = 0x10010a68, diff = -4
arr[8]:
&x = 0x403030, &y = 0x403020, diff = 16
Linux: &x = 0x10010a64, &y = 0x10010adc, diff = -4
arr[9]:
&x = 0x403030, &y = 0x403020, diff = 16
Linux: &x = 0x10010a64, &y = 0x10010adc, diff = -4
arr[10]:
&x = 0x403030, &y = 0x403020, diff = 16
Linux: &x = 0x10010a64, &y = 0x10010adc, diff = -4
5.
#include <stdio.h> int main (void) { int *p1, *p2; int q; p1 = &q; int r; p2 = &r; printf("p1 = %p, p2 = %p", p1, p2); return 0; }
Result: p1 = 0x22ccbc, p2 = 0x22ccb8(windows) p1 = 0xffc80754, p2 = 0xffc80750 (linux)
6.
Code:
#include <stdio.h> char *local_str() { char s[8] = "0123456"; return s; } char *local_str2() { char s[8] = "abcdefg"; return s; } char *static_str() { static char s[8] = "tuvwxyz"; return s; } char *malloc_str() { char *s = malloc(8); strcpy( s, "hijklmn" ); return s; } int main (void) { char *sp; sp = local_str( ); printf( "sp = %p(%s)\n", sp, sp ); strcpy(sp, "XXXXXXX"); printf("sp X'd = %p(%s)\n", sp, sp); sp = local_str(); local_str2(); printf( "sp = %p(%s)\n", sp, sp ); strcpy(sp, "XXXXXXX"); printf("sp X'd = %p(%s)\n", sp, sp); sp = static_str(); local_str2(); printf( "sp = %p(%s)\n", sp, sp ); strcpy(sp, "XXXXXXX"); printf("sp X'd = %p(%s)\n", sp, sp); sp = malloc_str(); local_str2(); printf( "sp = %p(%s)\n", sp, sp ); strcpy(sp, "XXXXXXX"); printf("sp X'd = %p(%s)\n", sp, sp); return 0; }
Results: Windows: sp = 0x22cc90(456) sp X'd = 0x22cc90(-0@) sp = 0x22cc90(efg) sp X'd = 0x22cc90(-0@) sp = 0x402000(tuvwxyz) sp X'd = 0x402000(XXXXXXX) sp = 0xfb01a0(hijklmn) sp X'd = 0xfb01a0(XXXXXXX)
Linux: sp = 0xffaa1724( þîÐ►) sp X'd = 0xffaa1724(XXXXXXX) sp = 0xffaa1724(abcdefg) sp X'd = 0xffaa1724(XXXXXXX) sp = 0x10010dc0(tuvwxyz) sp X'd = 0x10010dc0(XXXXXXX) sp = 0x10011008(hijklmn) sp X'd = 0x10011008(XXXXXXX)
I am unsure of what obersvation I need to make. In Windows, the original string which stores numbers returns the last 3 values only and in Linux the first string returns jibberish. In Windows, the strcopy method returns jibberish twice where in linux it works all 4 times.
7.
#include <stdio.h> struct { char my_char; short my_short; int my_int; long my_long; float my_float; double my_double; } my_struct; int main (void) { printf( "&my struct = %p\n", my_struct ); printf( "offsets:\n" "my_char: %ld\n" "my_short: %ld\n" "my_int: %ld\n" "my_long: %ld\n" "my_float: %ld\n" "my_double: %ld\n", (long)&my_struct - (long)&my_struct.my_char, (long)&my_struct - (long)&my_struct.my_short, (long)&my_struct - (long)&my_struct.my_int, (long)&my_struct - (long)&my_struct.my_long, (long)&my_struct - (long)&my_struct.my_float, (long)&my_struct - (long)&my_struct.my_double ); return 0; }
Results:
Windows:
offsets:
my_char: 0
my_short: -2
my_int: -4
my_long: -8
my_float: -12
my_double: -16
Linux:
offsets:
my_char: 0
my_short: -2
my_int: -4
my_long: -8
my_float: -12
my_double: -16
Results are exactly the same.
8.
#include <stdio.h> union{ char my_char; short my_short; int my_int; long my_long; float my_float; double my_double; } my_struct; int main (void) { printf( "&my struct = %p\n", my_struct ); printf( "offsets:\n" "my_char: %ld\n" "my_short: %ld\n" "my_int: %ld\n" "my_long: %ld\n" "my_float: %ld\n" "my_double: %ld\n", (long)&my_struct - (long)&my_struct.my_char, (long)&my_struct - (long)&my_struct.my_short, (long)&my_struct - (long)&my_struct.my_int, (long)&my_struct - (long)&my_struct.my_long, (long)&my_struct - (long)&my_struct.my_float, (long)&my_struct - (long)&my_struct.my_double ); return 0; }
Results:
Windows:
offsets:
my_char: 0
my_short: 0
my_int: 0
my_long: 0
my_float: 0
my_double: 0
Linux:
offsets:
my_char: 0
my_short: 0
my_int: 0
my_long: 0
my_float: 0
my_double: 0
9.
#include <stdio.h> int main (void) { char *sp1, *sp2, *sp3; sp1 = malloc( 10 ); sp2 = malloc( 10 ); printf("Address of sp1 = %p. Address of sp2 - %p.\n", sp1, sp2); printf("sp1 = %s\n", sp1); free( sp1 ); sp1[6] = 'd'; printf("sp1 = %s\n", sp1); sp3 = malloc( 10 ); printf("Address of sp1 = %p. Address of sp2 - %p. Address of sp3 - %p\n", sp1, sp2, sp3); return 0; }
Results:
Windows:
Address of sp1 = 0xfa0198. Address of sp2 - 0xfa01a8.
sp1 =
sp1 = ԝ aԝda
Address of sp1 = 0xfa0198.
Address of sp2 - 0xfa01a8.
Address of sp3 - 0xfa0198
Linux:
Address of sp1 = 0x10011008.
Address of sp2 - 0x10011018.
sp1 =
sp1 =
Address of sp1 = 0x10011008.
Address of sp2 - 0x10011018.
Address of sp3 - 0x10
10.
#include <stdio.h> char *local_str() { char s[8] = "0123456"; return s; } char *local_str2() { char s[8] = "abcdefg"; return s; } char *local_str3() { char s[8] = "abcdefg"; return s; } char *local_str4() { char s[8] = "abcdefg"; return s; } int main (void) { printf( "local_str = %p\n", local_str ); printf( "local_str2 = %p\n", local_str2 ); printf( "local_str3 = %p\n", local_str3 ); printf( "local_str4 = %p\n", local_str4 ); return 0; }
Results:
Windows:
local_str = 0x401050
local_str2 = 0x40106c
local_str3 = 0x401088
local_str4 = 0x4010a4
last 2 hexadecimal places in decimal:
local str = 5*16^1 = 80
local str2 = 6*16^1 + 12*16^0 = 108
local str3 = 8*16^1 + 8*16^0 = 136
local str4 = 10*16 + 4*1 = 164
All differences in string sizes in Windows are 28 which indicates that each memory allocation is 28 in size.
Linux:
local_str = 0x100004ac
local_str2 = 0x1000051c
local_str3 = 0x1000058c
local_str4 = 0x100005fc
last 3 hexadecimal places in decimal:
local str = 1196
local str2 = 1308
local str3 = 1372
local str4 = 1532
Difference str2 and str = 112
Difference str3 and str2 = 64
Difference str4 and str3 = 160
Which are all multiples of 16. In Linux, as opposed to Window's constant memory allocation of 28, Linux's memory allocations appear random. However, all of the sizes of allocations are multiples of 16 which could be significant.