Midterm Flashcards
why is this code “dangerous”?
- int test1 = 0;
- char line[20];
- int test2 = 0;
- scanf(“%s”, line);
scanf does not honour the size of the target address. it doesn’t let you tell it how much to read
reading input that goes beyond the end of the buffer will overwrite values of other variables (in this case, test1 and test2
why is this code “dangerous”?
int readData(char *string, int max) {
int read = -1;
FILE *in;
in = fopen( “in.txt”, “r” );
if (in != NULL) {
fgets( string, max, in );
read = strlen( string );
}
return read;
}
file is not closed using fclose.
-> the code leaks
could potentially cause the code to crash
- eg. someone could write code to call this function repeatedly
Here is a physical memory that is pointed by char *str.
How long is this string? (i.e. what will strlen(str) return?)
str -> [a][v][4][0][\0][E][\0][h][\0]
4
The string is terminated by the null terminator at str[4].
extra:
- The null terminator is essential because C does not store the length of a string explicitly
-> functions that work with strings rely on the \0 to know where the string ends.
explain why you would not test for NULL when writing test cases, even as an edge case. (3)
- testing is meant to simulate user input. users can’t input NULL
- Applying the principles of design by contract should catch programming errors (like passing NULL to a
function) - Passing NULL to a function would cause a Segmentation fault or Abort.
- A Segmentation fault or Abort isn’t a test failure, it’s a crash.
passing NULL to a function would cause ________________ or _________
segmentation fault or abort
what is the main purpose of testing code?
to simulate human interaction with our code
(user input)
what are the 3 general classifications of inputs we need to use to test our code?
- general cases
- valid, expected input - edge cases
- input is valid but looks weird - memory leaks
- use loops to run code repeatedly
- observation with tools like top (see man top) or profilers
how do you check for memory leaks in your code?
- use loops to run code repeatedly
- observation with tools like top or profilers
list three edge cases for the following in-place sorting routine:
void sort( int *array, int size );
- array is empty
- [], 0 - array has one value
- [1] - array has repeated values
[2, 2, 2]
the only output you receive when you run a program is Segmentation fault. Explain what tool you would use to identify the problem, and what the tool is helping you understand about the program.
asserts, debugger, print statements can all help but for this the best option is a debugger
a debugger helps you:
- step through your program line-by-line (observe the flow)
- helps you find where the code is crashing - watch variables as they change (observe the state)
- determine which variables have the wrong values that are causing the crash
Given the following function, what should be the pre and postconditions for the function, and what
should the loop invariant(s) be? Write your answer as a series of assertions. Give at least two examples of
each type
void substr(char *in, int start, int end, char *out) {
int i;
for (i = start; i < end; i++)
out[i - start] = in[i];
out[i] = ‘\0’;
}
// preconditions:
assert(in != NULL);
assert(out != NULL);
assert(start < end);
assert(start >= 0);
assert(end < strlen(in));
// loop invariant
assert(i - start >= 0);
assert(i - start < end);
// postconditions
assert(out[0] == in[start]);
assert(out[strlen(out)] == ‘\0’);
Below is a structure definition for a string data structure in C:
typedef struct STRING {
char *content;
int length;
} string;
Write a function that will return the index of a character in an instance of this string structure. For complete points, your code must apply the principles of design by contract (you must define pre and postconditions for this function). No invariant function is provided, you should write your own.
Here’s the prototype:
// return the index at the specified character in the string (similar to // Java’s String#indexOf
method). Returns -1 if not found.
int index_of(string *, char);
see notes
The degree of reliance on other modules/functions
is called ________
coupling
Higher coupling means higher __________ and we are more likely to be affected [positively/negatively] by changes
dependency
negatively
The degree to which a function adheres to one task is called __________
cohesion
_________ cohesion means doing many independent
tasks. is this good?
low
no. we want high cohesion. we dont want our functions doing many independent tasks
well designed programs should have:
______ cohesion. The elements of each module
should be closely related to one another.
– makes modules easier to use and makes the entire program easier to understand.
_______coupling. Modules should be as independent
of each other as possible.
– makes it easier to modify the program and reuse modules.
high
low
high cohesion means the elements of each module are what? how does this help?
closely related to each other
makes modules easier to use and makes the program easier to understand
low coupling means modules should be…
how does this help?
as independent of each other as possible
makes it easier to modify the program and reuse modules
The assembler translates the assembly to…
binary/machine code
The von Neumann Architecture
A “stored-program” computer architecture consists of: (4)
- input device
- output device
- memory unit
- central processing unit
what is piping for?
piping redirects standard output from one program to another to be processed as standard input
transfers standard output to some other destination
what are the key differences between C and Java (7/8)
- C doesn’t have objects
- no String class. char arrays are strings - C doesn’t garbage collect
- Java destroys unused arrays and frees memory for you. C does not do this - C doesn’t have exceptions
- because it doesn’t have objects
- you must handle exceptional cases yourself - C does not check bounds for you
- will allow you to overflow and overwrite other blocks of memory - C has no concept of information hiding
- everything is public - variables can be used without being initialized
- arrays
- not bounds checked
- array size must be initialized. C doesn’t do this for you. eg. char name[]; // ERROR
- array data isn’t initialized with 0s (depends)
- you should initialize them yourself - C gives you direct access to memory
- there are types but they are just representation of the bits & bytes in memory
- in Java, bits & bytes are abstracted away into types
what is important about C not having objects
- no string class. char arrays are strings
- no exceptions. must do that shit yourself