lec 2
约 484 个字 29 行代码 预计阅读时间 2 分钟
Intro to C¶
Types of memory in C¶
● Stack Memory
Local variables allocated within functions. This memory is destroyed and may be reused after a function exits.
Not initialized by default. Will reflect whatever happened to be in that piece of memory.
● Static Memory
Variables declared outside any function, and variables declared with “static”.
A single copy is stored, at a predefined and unchanging memory address.
Initialized to zero by default.
● Heap Memory
Explicitly allocated (malloc) and freed (free).
After being freed, memory may be reused (in whole or in part) for future allocations.
Not initialized by default. Will reflect whatever happened to be in that piece of memory.
Memory safety¶
There are many ways that running C programs can get corrupted. These can result in mysterious and baffling bugs. Some examples:
- Use-after-free: if a program frees a region of memory, but keeps using it.
- Double-free: if a program frees a region of memory twice instead of once.
- Uninitialized memory: if a program uses memory that was never initialized.
- Buffer overflow: if a program modifies memory beyond the end of a region.
- Memory leak: if a program allocates memory, but never frees it.
- Type confusion: if a program unintentionally uses the wrong data type to access a variable in memory
Sorts of pointers¶
int *a; // pointer to int
float *b; // pointer to float
int **c; // pointer to pointer to int
char (*d)(int); // pointer to a function (int -> char)
char (**e)(int); // pointer to pointer to function (int -> char)
void *f; // pointer to untyped memory
void **g; // pointer to pointer to untyped memory
下面实例代码中的 i2txt
就是一个 pointer to function
#include <iostream>
char* i2txt(float);
int main() {
std::cout << i2txt(10);
}
char* i2txt(int) {
// ... stuff
}
Pointer arithmetic¶
Pointer arithmetic: 指针运算
- Dereferencing the nth element of an array (
array[n]
) is the same as dereferencing the memory at \(n\) plus the array pointer (*(array + n)
) - Taking a reference to the nth element of an array (
&array[n]
) is the same as adding \(n\) to the array pointer (array + n
). - But wait…
&my_array[3]
was0x2FBC
, which is \(12\) more than0x2FB0
! - This is because pointer arithmetic multiplies by the size of the underlying
data type!
(long) (my_array + 3) == ((long) my_array) + 3 * sizeof(int)
Common memory functions¶
malloc(n)
: allocates a region of n bytes from heap memory, and returns a pointer to the start of it. If there’s no memory left to allocate, returns NULL.free(ptr)
: frees the region of memory starting at ptr that was previously allocated by malloc. If ptr is NULL, does nothing.memset(ptr, v, n)
: sets every byte fromptr[0]
toptr[n-1]
to v.memmove(dst, src, n)
: copiessrc[0]...src[n-1]
todst[0]...dst[n-1]
memcpy(dst, src, n)
: alternate faster version ofmemmove
, which may misbehave if dst and src overlap in any way. (Discouraged! Prefermemmove
.)strlen(str)
: computes and returns the length of str, based on finding its null terminator. Will misbehave if the null terminator is missing!strcmp(a, b)
: compares two strings a and b, and returns an integer < 0, == 0, or > 0, depending on whether a < b, a == b, or a > b.strcpy(dst, src)
: equivalent tomemcpy(dst, src, strlen(src)+1)
(包括 null 终止符)
Bitwise operators¶
unsigned int my_int;
// Set the Nth bit of an integer:
my_int |= 1 << N;
// Clear the Nth bit of an integer
my_int &= ~(1 << N);
// Check if any bits in MASK are set
if (my_int & MASK) { /* ... */ }
// Check if all bits in MASK are set
if ((my_int & MASK) == MASK) { /* ... */ }
// Check if integer is a power of two
if (my_int && !(my_int & (my_int - 1))) { /* ... */ }
Created: January 10, 2024