C Programming Review
Is the following code valid? If so, why? Where is output located? char *foo(int var){ static char output[20]; snprintf(output, 20, "%d", var); return output; }
yes the static memory of output
What is the printf specifier to print a string, int, or char?
%s %d %c
Deferencing pointers
&
Address-of operator
*
Pointer arithmetic
+1 == +size of pointer
sizeof char
1 byte
ointer Arithmetic. Assume the following addresses. What are the following shifts? char** ptr = malloc(10); //0x100 ptr[0] = malloc(20); //0x200 ptr[1] = malloc(20); //0x300 * `ptr + 2` * `ptr + 4` * `ptr[0] + 4` * `ptr[1] + 2000` * `*((int)(ptr + 1)) + 3`
108?
What should the following usually return? int *ptr; sizeof(ptr); sizeof(*ptr);
4 bytes and 4 bytes
What does the following print out int main(){ fprintf(stderr, "Hello "); fprintf(stdout, "It's a small "); fprintf(stderr, "World\n"); fprintf(stdout, "place\n"); return 0; }
It's a small place Hello World
Buffering of stdout
Most programming languages offered buffered I/O features by default, since it makes generating output much more efficient. These buffered I/O facilities typically "Just Work" out of the box. But sometimes they don't. When we say they "don't work" what we mean is that excess buffering occurs, causing data not to be printed in a timely manner. This is typically fixed by explicitly putting a "flush" call in the code, e.g. with something like sys.stdout.flush() in Python, fflush(3) in C, or std::flush in C++.
fileio POSIX vs. C library
The C POSIX library is a specification of a C standard library for POSIX systems. It was developed at the same time as the ANSI C standard. Some effort was made to make POSIX compatible with standard C; POSIX includes additional functions to those introduced in standard C.
Simple C string functions (strcmp, strcat, strcpy)
The strcmp() function compares the two strings s1 and s2. It returns an integer less than, equal to, or greater than zero if s1 is found, respectively, to be less than, to match, or be greater than s2. The strncmp() function is similar, except it compares only the first (at most) n bytes of s1 and s2. The strcat() function appends the src string to the dest string, overwriting the terminating null byte ('\0') at the end of dest, and then adds a terminating null byte. The strings may not overlap, and the dest string must have enough space for the result. If dest is not large enough, program behavior is unpredictable; buffer overruns are a favorite avenue for attacking secure programs. The strncat() function is similar, except that * it will use at most n bytes from src; and * src does not need to be null-terminated if it contains n or more bytes. As with strcat(), the resulting string in dest is always null- terminated. If src contains n or more bytes, strncat() writes n+1 bytes to dest (n from src plus the terminating null byte). Therefore, the size of dest must be at least strlen(dest)+n+1. A simple implementation of strncat() might be: char * strncat(char *dest, const char *src, size_t n) { size_t dest_len = strlen(dest); size_t i; for (i = 0 ; i < n && src[i] != '\0' ; i++) dest[dest_len + i] = src[i]; dest[dest_len + i] = '\0'; return dest; } The strcpy() function copies the string pointed to by src, including the terminating null byte ('\0'), to the buffer pointed to by dest. The strings may not overlap, and the destination string dest must be large enough to receive the copy. Beware of buffer overruns! (See BUGS.) The strncpy() function is similar, except that at most n bytes of src are copied. Warning: If there is no null byte among the first n bytes of src, the string placed in dest will not be null-terminated. If the length of src is less than n, strncpy() writes additional null bytes to dest to ensure that a total of n bytes are written. A simple implementation of strncpy() might be: char * strncpy(char *dest, const char *src, size_t n) { size_t i; for (i = 0; i < n && src[i] != '\0'; i++) dest[i] = src[i]; for ( ; i < n; i++) dest[i] = '\0'; return dest; }
String truncation
The strdup() function returns a pointer to a new string which is a duplicate of the string s. Memory for the new string is obtained with malloc(3), and can be freed with free(3). The strndup() function is similar, but copies at most n bytes. If s is longer than n, only n bytes are copied, and a terminating null byte ('\0') is added. strdupa() and strndupa() are similar, but use alloca(3) to allocate the buffer. They are available only when using the GNU GCC suite, and suffer from the same limitations described in alloca(3).
String duplication
The strdup() function returns a pointer to a new string which is a duplicate of the string s. Memory for the new string is obtained with malloc(3), and can be freed with free(3). The strndup() function is similar, but copies at most n bytes. If s is longer than n, only n bytes are copied, and a terminating null byte ('\0') is added. strdupa() and strndupa() are similar, but use alloca(3) to allocate the buffer. They are available only when using the GNU GCC suite, and suffer from the same limitations described in alloca(3).
C Strings representation
an array of characters
char p[]vs char* p
array vs pointer
memory out of bounds errors
can't store anything when there isnt room
How do we prevent double free errors?
delete a freed pointer
sizeof x vs x*
depends on what x is but the pointer is 4 bytes
Heap memory lifetime
forever
double-free error
free will fail when a string is already free
Calls to heap allocation
malloc
C Strings as pointers
points to the first character in the array
C io fprintf and printf
print to a file and print
POSIX file IO (read, write, open)
read() attempts to read up to count bytes from file descriptor fd into the buffer starting at buf. On files that support seeking, the read operation commences at the file offset, and the file offset is incremented by the number of bytes read. If the file offset is at or past the end of file, no bytes are read, and read() returns zero. If count is zero, read() may detect the errors described below. In the absence of any errors, or if read() does not check for errors, a read() with a count of 0 returns zero and has no other effects. According to POSIX.1, if count is greater than SSIZE_MAX, the result is implementation-defined; see NOTES for the upper limit on Linux. write() writes up to count bytes from the buffer starting at buf to the file referred to by the file descriptor fd. The number of bytes written may be less than count if, for example, there is insufficient space on the underlying physical medium, or the RLIMIT_FSIZE resource limit is encountered (see setrlimit(2)), or the call was interrupted by a signal handler after having written less than count bytes. The open() system call opens the file specified by pathname. If the specified file does not exist, it may optionally (if O_CREAT is specified in flags) be created by open(). The return value of open() is a file descriptor, a small, nonnegative integer that is used in subsequent system calls (read(2), write(2), lseek(2), fcntl(2), etc.) to refer to the open file. The file descriptor returned by a successful call will be the lowest-numbered file descriptor not currently open for the process.
static memory
set size
What are the differences between the following two declarations? What does sizeof return for one of them? char str1[] = "bhuvan"; char *str2 = "another one";
srt1 is the size of the whole thing str2 is only the size of the pointer
What is the & operator? How about *?
the addresses of each of the variables to look like this. &bhuvan // 0x100 &bhuvan.firstname // 0x100 = 0x100+0x00 &bhuvan.lastname // 0x114 = 0x100+0x14 &bhuvan.phone // 0x128 = 0x100+0x28 pointer and deallocate