Docstoc

Interfaces

Document Sample
Interfaces Powered By Docstoc
					      Lecture 3
        Interfaces
   Pointers to Functions
  Memory bugs, File I/O
Variables – the special kind
                 Interfaces
• A definition of a set of functions that
  provide a coherent module (or library)
  – Data structure (e.g., list, binary tree)
  – User interface (e.g., drawing graphics)
  – Communication (e.g., device driver)
       Interface - modularity
• Hide the details of implementing the
  module from its usage
  – Specification – “what”
  – Implementation – “how”
  Interface – information hiding
• Hide “private” information from outside
  – The “outside” program should not be able to
    use internal variables of the module
  – Crucial for modularity


• Resource management
  – Define who controls allocation of memory
  Example interface - StrStack
• A module that allows to maintain a stack of
  strings
• Operations:
  – Create new
  – Push string
  – Pop string
  – IsEmpty


[See attached StrStack.h]
      Implementation of StrStack
Decision #1: data structure

•   Linked list
•   Array (static? dynamic?)
•   Linked list of arrays
•   …

We choose linked list for simplicity
   Implementation of StrStack
Decision #2: Resource allocation

• Duplicated strings on stack or keep pointer
  to original?
• If duplicate, who is responsible for freeing
  them?

We choose not to duplicate --- leave this
 choice to user of module
   Implementation of StrStack
• See StrStack.c
                 Using StrStack
int main()
{
  char *Line;
  StrStack *Stack = StrStackNew();

    while( (Line = ReadLine()) != NULL   )
      StrStackPush( Stack, Line );

    while( (Line = StrStackPop(Stack)) != NULL )
    {
      printf("%s\n", Line );
      free( Line );
    }
    return 0;
}
         Interface Principles
Hide implementation details

• Hide data structures
• Don’t provide access to data structures
  that might be changed in alternative
  implementation
• A “visible” detail cannot be later changed
  without changing code using the interface!
         Interface Principles
Use small set of “primitive” actions

• Provide to maximize functionality with
  minimal set of operations
• Do not provide unneeded functions “just
  because you can”
         Interface Principles
Don’t reach behind the back

• Do not use global variables or unexpected
  side effects
• Do not assume specific order of operations
  by the user
  – Such assumptions suggest the set of
    primitives is wrong
          Interface Principle
Consistent Mechanisms

• Do similar things in a similar way

  – strcpy(dest, source)
  – memcpy(dest, source)
         Interface Principle
Resource Management

• Free resource at the same level it was
  allocated
• Assumptions about resources
Pointers to functions
          Pointers to Functions
• C/C++ allow to have a pointer to a function

int foo(int x)
{…}
main()
{
  int (*func)(int); // func is a pointer to a function
  func = &foo;
  func = foo; // same
  int x = (*func)(7); // same as x = foo(7)
}
Example: Numerical Integrator
    Example: Numerical Integrator
double
numericalIntegration( double a, double b,
                        double (*func)(double), int k )
{
  double delta = (b - a)/k;
  double Sum = 0;

    for( double x = a+0.5*delta; x < b; x+= delta )
      Sum += (*func)(x);

    return Sum*delta;
}

See NumericalIntergator.c
         “Generic” interface
• Pointers to functions provide a way to write
  code that receives functions as arguments
• For example sorting – you can apply
  different comparison functions
  – increasing and decreasing order can be
    computed using the same algorithm code
  – Different data types can be sorted using the
    same algorithm code
              Example: qsort
Library procedure:
qsort( void *base,
        size_t n,
        size_t size,
        int (*compare)(void const*,
                      void const *)
);
• base – start of an array
• n – number of elements
• size – size of each element
• compare – comparison function
              Using qsort
int compareInt(void const *p, void const *q)
{
  int a = *(int const*)p;
  int b = *(int const*)q;
  if( a < b )
     return -1;
  return a > b;
}
…
  int array[10] = { … };
  qsort( array, 10, sizeof(int), compareInt
  );
                  argv & argc
• To pass command line arguments to our program
  we should use the following main declaration:
      main(int argc, char* argv[]) { ...


                          char** argv
                          char argv[][]

• Compare to main(String[] args)
  in java.

• Unlike java the first argument is
  the name of the program itself.
      argv & argc: example
• $ prog1 –u danny –p 1234

 argc = 5
 argv[0] = “prog1”
 argv[1] = “-u”
  ...
 argv[4] = “1234”
 Always: argv[argc] = 0
                       File I/O
•File I/O is mostly similar to stdin & stdout I/O.
•Most I/O functions we encountered have a “file”
 counterpart which receives a FILE pointer (handle).
•Examples:

getchar(void)            fgetc(FILE*)
scanf(const char *,...) fscanf(FILE*, const char*,...)
printf(const char *,...) fprintf(FILE*, const char*,...)


•The standard streams (stdin, stdout, stderr) are
 also of FILE* type.

See related man pages: fprintf, fscanf, etc.
     File I/O example: mywc
#include <stdio.h>
#include <errno.h>
#include <ctype.h>
main(int argc, char* argv[]) {
  FILE* fp;
  int wc = 0, ch;
  if (argc != 2) {
     printf("Usage: mywc <filename>\n");
     exit(1);
  }
  errno = 0;
  fp = fopen(argv[1], "r");
   if (fp == NULL) {
     perror(“”);
     exit(1);
   }
    while (1) {
               File I/O example
      while ((ch = fgetc(fp)) != EOF && isspace(ch))
        ;
      if (ch == EOF)
        break;
      wc++;
      while ((ch = fgetc(fp)) != EOF && !isspace(ch))
        ;
      if (ch == EOF)
        break;
    }
    fclose(fp);
    printf("There are %d words in %s\n", wc, argv[1]);
    return 0;
}

Related man pages: fopen, fclose
Inter module variables’ scope
                Static variables
•   Static variables in a function keep their value
    for the next call to the function
    –   Allocated on the heap

(1)void getUniqueID() {
(2) static int id=0;
(3) id++;
(4) return id;
(5)}

(6)int main() {
(7) int i = getUniqueID(); //i=1
(8) int j = getUniqueID(); //j=2
(9)}
          Static variables, cont.
• “static” variable on the global scope
  – Available only in the current module
• “extern” variable
  – Defined outside the module

file1.c            file2.c

int y;             extern int y; //y from file1.c
static int x;      extern int x;//x defined elsewhere
int myFunc() {     int myFunc() {
   int x;//error        int y; //error
   …                    …
}                  }
               C’s “const”
• C’s “const” is a qualifier that can be
  applied to the declaration of any variable to
  specify its value will not be changed.

     const double e = 2.71828;
     const char msg[] =“Warning:”;
     msg[1] = „w‟;   // illegal !
                      C’s “const”
• Do not confuse what the “const” declaration
  “protects” !
  –   A pointer to a const variable:
int const * p = {1,2,3};               1   2   3
p[1] = 1; // illegal!
*(p+1) = 1; // illegal!
p = NULL; //legal

  –   A const pointer to a variable:   1   2   3
int* const const_p = {1,2,3};
const_p[1] = 0; // legal !
const_p = NULL; // illegal!
               Pointer’s Syntax
• Compare:
(1)int * const p = {1,2,3};
(2)const int * p = {1,2,3};
(3)int const * p = {1,2,3};

• (2) and (3) are synonyms in C
  to a pointer to a const array.
  We encourage right to left reading of declarations, to
  achieve better readability and avoid errors.`
• DO NOT TRY THIS AT HOME 
      Pointers and User Defined
                Types
struct Complex {
   int img;
   int real;
};
Complex comp2;
Complex const comp1 = comp2;
             //ok,initialize using comp2
Complex comp3;

comp1.img = 3;
             // illegal ! comp1 value is constant
comp1=comp3;
             // illegal ! comp1 value is constant

• All the members of a const variable are immutable !
       Compare to Java’s “final”
• All (methods as well as data ) are Class members.
• “final” makes primitive types constants and references to objects
  constant.
• The values inside the referred objects are not constant !

  final int LIMIT = 10;
  int LIMIT = 11;// illegal !
  final MyObject obj1 = MyObject();

  MyObject obj2 = NULL;
  MyObject obj3 = MyObject();
  obj2 = obj1;//fine, both point now to the same object
  obj1 = obj3; // illegal !
  obj1.setSomeValue(5); // legal !
* Because All are class members you would normally use them as
   class constants and declare them as “static final”
                  “Const” Usage
• The const declaration can (and should !) be used in
  the definition of a function’s arguments, to indicate
  it would not change them:
 int strlen(const char []);

• Why use ? (This is not a recommendation but a
  must)
   – Clearer code
   – Avoids errors
   – Part of the interfaces you define!

• We will see more of “const” meaning and usage
  when we get to C++
    Memory related bugs



•   Memory leaks.
•   Accessing random/freed memory
    addresses.
                malloc_stats()
• By including malloc.h you can use the
  malloc_stats() function which prints to the
  stderr information about the amount of used
  memory.
• Example:
           . . .
           malloc_stats();
           destroyDictionary(dict);
           malloc_stats();
           . . .
               malloc_stats() cntd.

With memory leak:       Without memory leak:

Arena 0:                Arena 0:
system bytes   = 8140   system bytes   = 8124
in use bytes   = 6860   in use bytes   = 6860
. . .                   . . .
Arena 0:                Arena 0:
system bytes   = 8140   system bytes   = 8124
in use bytes   = 4084   in use bytes   = 4
. . .                   . . .
                        mtrace
• Log all memory allocations to a file.
  – The file name is contained in the MALLOC_TRACE
    environment variable.
  – For example:
    $setenv MALLOC_TRACE ~/plab/ex1/trace
• Analyze the file to find memory leaks using the
  mtrace utility.
• The program must:
  – be compiled with –g flag
  – #include <mcheck.h>
                         mtrace example
The program:
#include <mcheck.h>
int main() {
  mtrace(); // later we can call muntrace()
  . . .
  muntrace();
  return 0;
}
The log file looks like this:
=   Start
@   [0x80486fd] + 0x804a0e0 0x8
@   [0x804887d] + 0x804a0f0 0x8
@   [0x8048c7d] + 0x804a100 0x14
@   /lib/libc.so.6:(__strdup+0x29)[0x400d7a29] + 0x804a118 0x5
@   [0x8048c7d] + 0x804a128 0x14
@   /lib/libc.so.6:(__strdup+0x29)[0x400d7a29] + 0x804a140 0x3
@   [0x8048c7d] + 0x804a150 0x14
.   . .
               mtrace example cntd.
The result of analysis (mtrace ex1 $MALLOC_TRACE)

Memory not freed:
-----------------
Address    Size Caller
0x0804a100 0x14 at /home/mush/plab/ex1/strBinTree.c:65
0x0804a128 0x14 at /home/mush/plab/ex1/strBinTree.c:65
0x0804a150 0x14 at /home/mush/plab/ex1/strBinTree.c:65

Another example:
Memory not freed:
-----------------
Address   Size Caller
0x0804a118 0x5 at /lib/libc.so.6:(__strdup+0x29)[0x400d7a29]
0x0804a140 0x3 at /lib/libc.so.6:(__strdup+0x29)[0x400d7a29]
               MALLOC_CHECK_
• By setting this environment variable to 0, 1, 2
  we can handle some bugs, most notably freeing twice
  the same memory.
• Usually double free causes segmentation fault.
• When MALLOC_CHECK_ is 0 freeing twice works.
• When MALLOC_CHECK_ is 1 an error message is
  printed.
  – Example:
     free(): invalid pointer 0x80497b8!
• When MALLOC_CHECK_ is 2 the program (gracefully)
  aborts.
                    ElectricFence
 ElectricFence   is a library which allows to catch
  accesses to memory that was already freed,
  as well as off-by-one errors.
 It will cause the program to segfault in the above
  cases, which is usually better than continue running
  and have unpredictable errors later.



 Example:
 char* a = (char*)malloc(100*sizeof(char));
 . . .
 a[100] = 'c'; // ElectricFence will cause segfault
               ElectricFence cntd.
 Example:
 Node* n1 = (Node*)malloc(sizeof(Node));
 . . .
 free(n1);
 . . .
 n1->x = 7; // ElectricFence will cause segfault


 Touse ElectricFence you should link your program
 with the efence library.
   For example:
    g++ prog1.o list.o read.o -lefence
         Commercial products
• Purify
• BoundsChecker
• MS’s VisualStudio

				
DOCUMENT INFO
Shared By:
Categories:
Tags:
Stats:
views:4
posted:10/15/2011
language:English
pages:45