1. C Memory Layout
1.1 Where Do the Variables Go?
1.2 The Stack
1.2.1 Stack misuse example
gpt4解释:
在C语言中,从函数返回指向本地变量的指针是不安全的,原因在于局部变量(本地变量)的生命周期。当一个函数被调用时,它的局部变量在栈上分配内存。这些局部变量只在函数执行期间存在,一旦函数返回,这部分栈内存就不再属于该函数,会被释放或用于其他目的。
如果你从一个函数返回一个指向其局部变量的指针,那么当函数执行结束后,该指针将指向一个已经不再有效的内存区域。这种情况被称为“悬垂指针”(dangling pointer)。尝试访问通过这样的指针引用的数据是非常危险的,因为它可能导致未定义的行为,比如访问或修改其他变量的值,或者导致程序崩溃。
int* func() {int local_var = 10;return &local_var; // 返回指向局部变量的指针
}int main() {int *ptr = func(); // ptr 现在是悬垂指针// 使用 ptr 的行为是未定义的return 0;
}
在这个例子中,函数 func
返回了一个指向其局部变量 local_var
的指针。但是当 func
返回时,local_var
的生命周期结束了,因此 ptr
变成了悬垂指针。
为了避免这种问题,可以:
- 使用全局或静态变量。
- 分配动态内存(使用
malloc
或类似函数),但这要求调用者负责释放内存。 - 将数据传递给调用函数,而不是尝试从函数返回指向局部数据的指针。
1.3 Static Data
2. Addressing and Endianness
2.1 Adress
2.2 Endianness
Big-endian:高位字节存入低地址,低位字节存入高地址
Little-endian:低位字节存入低地址,高位字节存入高地址
//但在计算机内部一般都是小端序,与人类的阅读习惯相反,但更符合计算机读取内存的方式,因为CPU读取内存中的数据时,是从低地址向高地址方向进行读取的
举例如下图:
2.3 Common mistakes
寄存器是没有小端序 大端序的概念的。
3. Dynamic Memory Allocation
3.1 Dynamic Memory Allocation
3.2 sizeof()
3.3 sizeof() and Arrays
3.4 Allocating Memory
3.6 Releasing Memory
3.7 Calloc
3.8 Realloc
3.9 Dynamic Memory Example
4. Common Memory Problems
4.1 Know Your Memory Errors
4.2 Common Memory Problems
4.3 Using Uninitialized Values
ps,这之后的页面略,因为全是一些example,可以去原pdf看