SE250:lab-2:ssre005

From Marks Wiki
Jump to navigation Jump to search

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.