Instructor:
How do we make sure that we access memory correctly?
What do you make of this program?
int main() { int *p = (int*) malloc (sizeof(int)); *p = 2123456789; printf ("(float)*p = %f\n", (float)*p); /* loss of precision */ printf ("*(float*)p = %f\n", *(float*)p); /* rubbish */ int i = 2; char s[] = "three"; printf ("i*s = %ld\n", i*(long)s);}
$ clang -m32 typing-00.c && ./a.out(float)*p = 2123456768.000000*(float*)p = 96621069057346178268049192388430659584.000000i*s = -1047484
val x : Int = "Hello".asInstanceOf[Int]java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer
What do you make of the following program?
int main () { float f = 10; int a[] = { 10 }; short i = 10; printf ("f=%f, a[0]=%d i=%d\n", f, a[0], i); a[-1] = 2123456789; printf ("f=%f, a[0]=%d i=%d\n", f, a[0], i); /* Write int to a short */ a[1] = 2123456789; printf ("f=%f, a[0]=%d i=%d\n", f, a[0], i); /* Write int to a float */}
$ clang -m32 typing-03.c && ./a.outf=10.000000, a[0]=10 i=10f=10.000000, a[0]=10 i=32401f=96621069057346178268049192388430659584.000000, a[0]=10 i=32401
int main() { int x = 2123456789; double y = x; printf ("x=%d, y=%f\n", x, y); double *p = &x; /* Obtain int*, cast to double* */ double z = *p; /* Read a double from an int memory location */ printf ("x=%d, z=%f\n", x, z);}
$ gcc typing-06.c && ./a.outx=2123456789, y=2123456789.000000x=2123456789, z=38685644468023060038942720.000000
int main() { int* ip = (int*) malloc (sizeof(int)); *ip = 10; free(ip); float* fp = (float*) malloc (sizeof(float)); /* Float's likely memory location of int */ *fp = 10; printf ("*fp=%f, *ip=%d\n", *fp, *ip); /* Read an int from a float */ printf (" fp=%p, ip=%p\n", fp, ip); /* Addresses likely the same */}
$ gcc typing-07.c && ./a.out*fp=10.000000, *ip=1092616192 fp=0x1063010, ip=0x1063010
To be safe, Java and Scala do the following
free
Java
Object[] bs = new Object[4];Object b = bs[-1];
Scala
val bs = Array(1, 2, 3, 4)val b = bs(-1)
java.lang.ArrayIndexOutOfBoundsException: -1
class A { int x; }class B extends A { float y; }class C extends A { char c; }static void f (B b) { A a = b; /* upcast always safe */}static void g (A a) { B b = (B) a; /* downcast must be checked */}f (new B());g (new C());
class A(val x: Int)class B(val y: Float) extends A(1)class C(val c: Char) extends A(2)/* upcast always safe */def f (b: B) = { val a: A = b }/* downcast must be checked */def g (a: A) = { val b: B = a.asInstanceOf[B] }f (new B(2.0))g (new C('c'))
java.lang.ClassCastException: C cannot be cast to B
null
40min
Use illustrations of memory on the board: int vs. fixed-point numbers