Skip to main content

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

fds

讲解

(1)stack

Stack frame: 运行时函数分配的局部 automatic 变量、函数参数、返回数据、返回地址等

As you do recursive calls, a new stack frame added, the stack is going downward.

pic (1)

#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

20210330193414

(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 together a bunch of object files (.o files) into a binary executable

gcc recurse map -o map.o