Skip to content

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] was 0x2FBC, which is \(12\) more than 0x2FB0!
  • This is because pointer arithmetic multiplies by the size of the underlying data type! (long) (my_array + 3) == ((long) my_array) + 3 * sizeof(int)

Alt text

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 from ptr[0] to ptr[n-1] to v.
  • memmove(dst, src, n): copies src[0]...src[n-1] to dst[0]...dst[n-1]
  • memcpy(dst, src, n): alternate faster version of memmove, which may misbehave if dst and src overlap in any way. (Discouraged! Prefer memmove.)
  • 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 to memcpy(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))) { /* ... */ }

Last update: January 10, 2024
Created: January 10, 2024