CPSC 213 } C Vs

CPSC 213 } C Vs

Reading Java Hello World... ‣ Textbook import java.io.*; public class HelloWorld { • New to C, Understanding Pointers, The malloc and free Functions, Why Dynamic Memory Allocation public static void main (String[] args) { System.out.println("Hello world"); • 2ed: "New to C" sidebar of 3.4, 3.10, 9.9.1-9.9.2 } • 1ed: "New to C" sidebar of 3.4, 3.11,10.9.1-10.9.2 CPSC 213 } C vs. Java C Hello World... Introduction to Computer Systems #include <stdio.h> main() { printf("Hello world\n"); Unit 1f } C, Pointers, and Dynamic Allocation 1 2 3 4 Java Syntax... vs. C Syntax New in C: Pointers C and Java Arrays and Pointers ‣ source files ‣ source files ‣ pointers: addresses in memory 0x00000000 ‣ In both languages 0x00000001 • .java is source file • .c is source file • locations are first-class citizens in C • an array is a list of items of the same type 0x00000002 • .h is header file • can go back and forth between location and value! • array elements are named by non-negative integers start with 0 0x00000003 ‣ including packages in source ‣ including headers in source ‣ pointer declaration: <type>* 0x00000004 • syntax for accessing element i of array b is b[i] • import java.io.* • #include <stdio.h> • int* b; // b is a POINTER to an INT 0x00000005 ‣ In Java ‣ printing ‣ printing 0x00000006 • printf("blah blah\n"); ‣ getting address of object: & • variable a stores a pointer to the array • System.out.println("blah blah"); . Pointers in C • int a; // a is an INT • b[x] = 0 means m[m[b] + x * sizeof(array-element)] ← 0 ‣ compile and run ‣ compile and run . • int* b = &a; // b is a pointer to a . • javac foo.java • gcc -g -o foo foo.c ‣ In C • ./foo 0x3e47ad40 • java foo ‣ de-referencing pointer: * • variable a can store a pointer to the array or the array itself • at Unix command line shell prompt • at command line (Linux, Windows, Mac) • a = 10; // assign the value 10 to a 0x3e47ad41 (Linux, Mac Terminal, Sparc, • b[x] = 0 means m[b + x * sizeof(array-element)] ← 0 0x3e47ad42 Cygwin on Windows) • *b = 10; // assign the value 10 to a or m[m[b] + x * sizeof(array-element)] ← 0 ‣ debug . ‣ edit, compile, run, debug (IDE) ‣ type casting is not typesafe . • dynamic arrays are just like all other pointers • gdb foo • Eclipse • char a[4]; // a 4 byte array . - stored in TYPE* • *((int*) a) = 1; // treat those four bytes as an INT 0xffffffff - access with either a[x] or *(a+x) 5 6 7 8 Example Example Pointer Arithmetic in C Question (from S3-C-pointer-math.c) ‣ The following two C programs are identical ‣ The following two C programs are identical ‣ Its purpose int *c; • an alternative way to access dynamic arrays to the a[i] int *a; int *a; int *a; int *a; void foo () { a[4] = 5; *(a+4) = 5; a[4] = 5; *(a+4) = 5; ‣ Adding or subtracting an integer index to a pointer // ... c = (int *) malloc (10*sizeof(int)); • results in a new pointer of the same type // ... ‣ For array access, the compiler would generate this code ‣ For array access, the compiler would generate this code • value of the pointer is offset by index times size of pointer’s referent c = &c[3]; *c = *&c[3]; • for example // ... r[0] ← a ld $a, r0 r[0] ← a ld $a, r0 - adding 3 to an int* yields a pointer value 12 larger than the original } r[1] ← 4 ld $4, r1 r[1] ← 4 ld $4, r1 r[2] ← 5 ld $5, r2 r[2] ← 5 ld $5, r2 ‣ Subtracting two pointers of the same type m[r[0]+4*r[1]] ← r[2] st r2, (r0,r1,4) m[r[0]+4*r[1]] ← r[2] st r2, (r0,r1,4) • results in an integer ‣ What is the equivalent Java statement to • gives number of referent-type elements between the two pointers • multiplying the index 4 by 4 (size of integer) to compute the array offset • multiplying the index 4 by 4 (size of integer) to compute the array offset • [A] c[0] = c[3]; • for example • [B] c[3] = c[6]; ‣ So, what does this tell you about pointer arithmetic in C? ‣ So, what does this tell you about pointer arithmetic in C? - (& a[7]) - (& a[2])) == 5 == (a+7) - (a+2) • [C] there is no typesafe equivalent ‣ other operators • [D] not valid, because you can’t take the address of a static in Java Adding X to a pointer of type Y*, adds X * sizeof(Y) • & X the address of X to the pointer’s memory-address value. • * X the value X points to 9 9 10 11 Looking more closely Looking more closely ‣ And in assembly language Example: Endianness of a Computer r[0] ← 0x2000 # r[0] = &c c = &c[3]; r[0] ← 0x2000 # r[0] = &c c = &c[3]; r[0] ← 0x2000 # r[0] = &c r[1] ← m[r[0]] # r[1] = c *c = *&c[3]; r[1] ← m[r[0]] # r[1] = c *c = *&c[3]; r[1] ← m[r[0]] # r[1] = c r[2] ← 12 # r[2] = 3 * sizeof(int) r[2] ← 12 # r[2] = 3 * sizeof(int) r[2] ← 12 # r[2] = 3 * sizeof(int) r[2] ← r[2]+r[1] # r[2] = c + 3 #include <stdio.h> r[2] ← r[2]+r[1] # r[2] = c + 3 r[2] ← r[2]+r[1] # r[2] = c + 3 m[r[0]] ← r[2] # c = c + 3 m[r[0]] ← r[2] # c = c + 3 m[r[0]] ← r[2] # c = c + 3 int main () { r[3] ← 3 # r[3] = 3 char a[4]; r[3] ← 3 # r[3] = 3 r[3] ← 3 # r[3] = 3 r[4] ← m[r[2]+4*r[3]] # r[4] = c[3] r[4] ← m[r[2]+4*r[3]] # r[4] = c[3] r[4] ← m[r[2]+4*r[3]] # r[4] = c[3] m[r[2]] ← r[4] # c[0] = c[3] *((int*)a) = 1; m[r[2]] ← r[4] # c[0] = c[3] m[r[2]] ← r[4] # c[0] = c[3] printf("a[0]=%d a[1]=%d a[2]=%d a[3]=%d\n",a[0],a[1],a[2],a[3]); } Before Before After ld $0x2000, r0 # r0 = &c ld (r0), r1 # r1 = c ld $12, r2 # r2 = 3*sizeof(int) 0x2000: 0x3000 0x2000: 0x3000 0x2000: 0x300c 0x3000: 0 0x3000: 0 0x3000: 0 add r1, r2 # r2 = c+3 0x3004: 1 0x3004: 1 0x3004: 1 st r2, (r0) # c = c+3 0x3008: 2 0x3008: 2 0x3008: 2 0x300c: 3 0x300c: 3 0x300c: 6 ld $3, r3 # r3 = 3 0x3010: 4 0x3010: 4 0x3010: 4 c[0] = c[3] ld (r2,r3,4), r4 # r4 = c[3] 0x3014: 5 0x3014: 5 0x3014: 5 st r4, (r2) # c[0] = c[3] 0x3018: 6 0x3018: 6 0x3018: 6 0x301c: 7 0x301c: 7 0x301c: 7 0x3020: 8 0x3020: 8 0x3020: 8 12 12 13 14 Dynamic Allocation in C and Java Considering Explicit Delete ‣ Let's extend the example to see • what might happen in bar() ‣ Programs can allocate memory dynamically ‣ Let's look at this example • and why a subsequent call to bat() would expose a serious bug • allocation reserves a range of memory for a purpose struct MBuf * receive () { struct MBuf * receive () { struct MBuf* mBuf = (struct MBuf*) malloc (sizeof (struct MBuf)); struct MBuf* mBuf = (struct MBuf*) malloc (sizeof (struct MBuf)); • in Java, instances of classes are allocated by the new statement ... ... return mBuf; • in C, byte ranges are allocated by call to malloc function return mBuf; } } ‣ Wise management of memory requires deallocation void foo () { void foo () { • memory is a scare resource struct MBuf* mb = receive (); struct MBuf* mb = receive (); Dynamic Allocation bar (mb); bar (mb); • deallocation frees previously allocated memory for later re-use free (mb); free (mb); } } • Java and C take different approaches to deallocation void MBuf* aMB; ‣ How is memory deallocated in Java? • is it safe to free mb where it is freed? • what bad thing can happen? void bar (MBuf* mb) { aMB = mb; } ‣ Deallocation in C void bat () { This statement writes to • programs must explicitly deallocate memory by calling the free function aMB->x = 0; unallocated (or re-allocated) memory. } • free frees the memory immediately, with no check to see if its still in use 15 16 17 18 Dangling Pointers Avoiding Dangling Pointers in C Avoiding dynamic allocation Reference Counting ‣ A dangling pointer is ‣ Understand the problem ‣ If procedure returns value of dynamically allocated object ‣ Use reference counting to track object use • a pointer to an object that has been freed • when allocation and free appear in different places in your code • allocate that object in caller and pass pointer to it to callee • any procedure that stores a reference increments the count • could point to unallocated memory or to another object • for example, when a procedure returns a pointer to something it allocates • good if caller can allocate on stack or can do both malloc / free itself • any procedure that discards a reference decrements the count ‣ Why they are a problem ‣ Avoid the problem cases, if possible • the object is freed when count goes to zero struct MBuf * receive () { • program thinks its writing to object of type X, but isn’t • restrict dynamic allocation/free to single procedure, if possible struct MBuf* mBuf = (struct MBuf*) malloc (sizeof (struct MBuf)); struct MBuf* malloc_Mbuf () { ... • it may be writing to an object of type Y, consider this sequence of events struct MBuf* mb = (struct MBuf* mb) malloc (sizeof (struct MBuf)); • don’t write procedures that return pointers, if possible return mBuf; mb->ref_count = 1; } • use local variables instead, where possible return mb; (1) Before free: (2) After free: void foo () { } - since local variables are automatically allocated on call and freed on return through stack aMB: 0x2000 aMB: 0x2000 struct MBuf* mb = receive (); dangling ‣ Engineer for memory management, if necessary bar (mb); void keep_reference (struct MBuf* mb) { pointer free (mb); void receive (struct MBuf* mBuf) { mb->ref_count ++; 0x2000: a struct mbuf 0x2000: free memory } ..

View Full Text

Details

  • File Type
    pdf
  • Upload Time
    -
  • Content Languages
    English
  • Upload User
    Anonymous/Not logged-in
  • File Pages
    2 Page
  • File Size
    -

Download

Channel Download Status
Express Download Enable

Copyright

We respect the copyrights and intellectual property rights of all users. All uploaded documents are either original works of the uploader or authorized works of the rightful owners.

  • Not to be reproduced or distributed without explicit permission.
  • Not used for commercial purposes outside of approved use cases.
  • Not used to infringe on the rights of the original creators.
  • If you believe any content infringes your copyright, please contact us immediately.

Support

For help with questions, suggestions, or problems, please contact us