Files and Memory
Files
I/O Streams
C High Level API
// character oriented
int fputc( int c, FILE *fp ); // rtn c or EOF on err
int fputs( const char *s, FILE *fp ); // rtn > 0 or EOF
int fgetc( FILE * fp );
char *fgets( char *buf, int n, FILE *fp );
// block oriented
size_t fread(void *ptr, size_t size_of_elements,
size_t number_of_elements, FILE *a_file);
size_t fwrite(const void *ptr, size_t size_of_elements,
size_t number_of_elements, FILE *a_file);
// formatted
int fprintf(FILE *restrict stream, const char *restrict format, ...);
int fscanf(FILE *restrict stream, const char *restrict format, ... );
C Streams: Char-by-Char
int main(void) {
FILE* input = fopen(“input.txt”, “r”);
FILE* output = fopen(“output.txt”, “w”);
int c;
c = fgetc(input);
while (c != EOF) {
fputc(output, c);
c = fgetc(input);
}
fclose(input);
fclose(output);
}
C Streams: Block-by-Block
#define BUFFER_SIZE 1024
int main(void) {
FILE* input = fopen("input.txt", "r");
FILE* output = fopen("output.txt", "w");
char buffer[BUFFER_SIZE];
size_t length;
length = fread(buffer, BUFFER_SIZE, sizeof(char), input);
while (length > 0) {
fwrite(buffer, length, sizeof(char), output);
length = fread(buffer, BUFFER_SIZE, sizeof(char), input);
}
fclose(input);
fclose(output);
}
Memory layout
讲解
(1)stack
Stack frame: 运行时函数分配的局部 automatic 变量、函数参数、返回数据、返回地址等
As you do recursive calls, a new stack frame added, the stack is going downward.
#include <stdio.h>
#include <stdlib.h>
/* A statically allocated variable */
int foo;
/* UNCOMMENT THIS LINE for 3.4.3*/
extern int recur(int i);
/* A statically allocated, pre-initialized variable */
volatile int stuff = 7;
int main(int argc, char* argv[]) {
/* A stack allocated variable */
volatile int i = 0;
/* Dynamically allocate some stuff */
volatile char* buf1 = malloc(100);
/* ... and some more stuff */
volatile char* buf2 = malloc(100);
recur(3);
return 0;
}
#0,#1:frame number
(2)heap
The Heap area is managed by malloc
, realloc
, and free
.
When you do malloc() to allocate new things,the heap is going upward.
When we run out of memory, the heap and stack run into each other.
(3)Uninitialized data(.bss--block started by symbol)
别名:ZI
data(ZeroInitialie data)
对于未初始化的全局变量和静态变量(全局 and 局部),程序运行 main 之前时会统一清零。即未初始化的全局变量编译器会初始化为 0
//两种均是
static int i;
int j;
(4)Initialized data(.data)
存储程序中已初始化的全局变量和静态变量(全局 and 局部)
进一步可分为RO
(read-only area) and RW
(read-write area)--字符串常量
char s[] = “hello world”;//RW
debug=1 ;//RW
const char* string = “hello world” ;
//“hello world”--RO ,character pointer variable string --RW
int main(){}
(5)text segment(.text)
Contains the code to be executed(read only)
全局区
全局区(static):也叫静态数据内存空间,存储全局变量和静态变量,全局变量和静态变量的存储是放一块的,初始化的全局变量和静态变量放一块区域,没有初始化的在相邻的另一块区域,程序结束后由系统释放。(不包含常量)
Thus,
类的静态成员变量本质上是全局变量,哪怕一个对象都不存在,类的静态成员变量也存在
类的静态成员函数本质上是全局函数
只是其作用域为局部作用域
Example
//main.cpp 程序代码区
int a = 0; //全局初始化区
char *p1; //全局未初始化区
main()
{
int b; //栈
char s[] = "abc"; //栈
char *p2; //栈
char *p3 = "123456"; //123456\0在常量区,p3在栈上。
static int c =0; //全局(静态)初始化区
p1 = (char *)malloc(10);
p2 = (char *)malloc(20); //分配得来得10和20字节的区域就在堆区。
strcpy(p1, "123456"); //123456\0放在常量区,编译器可能会将它与p3所指向的"123456"优化成一个地方。
}
From souce code to executable
Preprocess
Convert the source code file into a modified/expanded source code file
3 things:
- Macro substitution
- Comments are stripped off
- Expansion of the included files
gcc -E map.c
Compilation
生成汇编指令代码
gcc -S map.c -o map.S
gcc -S recurse.c -o recurse.S
Assembly
At this stage only the existing code is converted into machine language, the function calls like printf() are not resolved.
gcc -c map.c -o map
gcc -c recurse.c -o recurse
Link
link together a bunch of object files (.o files) into a binary executable
gcc recurse map -o map.o