uc_day02

一,C語言中的錯誤處理
1,錯誤處理方式
error.c


#include<stdio.h>
max(int x, int y){


  return x > y?x:y;
}


int main(){
  int r = max(3,4);
  printf("r=%d\n",r);
  return 0;
}


要求:返回最大值,如果相等,返回錯誤信息


#include<stdio.h>
max(int x, int y,int* r){
  if(x == y) return -1;
  *r = x>y?x:y;
  return 0;
}


int main(){
  int r;
  if(max(3,4,&r) == -1){
     printf("函數調用錯誤\n");
     return -1;
  }
 printf("r=%d\n",r);
  return 0;
}


出錯指針返回NULL,整數返回-1
C語言中如果返回值是void,有一個潛藏的含義,這個函數調用不會出錯




輸出參數的常用方法
2,錯誤處理
errno.c


#include<stdio.h>
#include<errno.h>
#include<string.h>
int main(){
  FILE* file = fopen("etc/passwd","r");
  if(file == NULL){
    printf("錯誤原因:%d\n",errno);
    printf("錯誤原因:%s\n",strerror(errno));


    printf("ERROR:%m\n");
    perror("錯誤");
    return -1;
  }
   printf("文件打開成功\n");
   return 0;
}
-------------------------------------------------
FILE* file2 = fopen("etc/passwd","w");
if(errno != 0){
  perror("打開文件失敗");
}
//不能用errno的值判斷剛纔的操作是否出錯,只能是當有錯誤發生時,
用errno來獲取錯誤的原因




二,環境表
env 是shell所擁有的環境變量,在內存中


env.c//程序中獲取這個環境表


#include<stdio.h>
#include<string.h>
int main(){
   extern char** environ;//聲明全局變量
   printf("environ=%p\n",viron);


   char** p = envirson;
   while(*p){
    printf("%s\n",*p);
    p++;
   }


   char value[100] = {};//將環境變量LANG的值保存在value中
   p = envirson;
   while(*p){
    //拿一個環境變量,看看是否是LANG,如果是,將=號後面的值保存到value中
    if(strncmp(*p,"LANG")==0){
       strcpy(value,*p+5);
       break;
    }
    p++;
   }   
   printf("value=%s\n",value);
   printf("===================\n");
   return 0;
}


這張環境表是一個char** environ[]類型的數組
最後的元素是一個NULL


------------------------------------------------
#include<stdio.h>
#include<stdlib.h>
int main(int argc,char** argv, char** env){
   extern char** environ;
   printf("environ=%p\n",environ);
   printf("env=%p\n",env);
   char* value = getenv("LANG");
   putenv("VAR=abc");
   putenv("LANG=c");//修改或添加環境添加。不存在,添加,存在,修改
   printf("value=%s\n",value);


   return 0;
}


三,內存管理
1,STL ==> 內存自動的分配和釋放
2,定位分配---C++
char buf[1024] = {};
int* p2 = new (buf)int;
*p2 = 200;
cout << *(int*)buf <<endl;
cout << *p2 << endl;
p2分配到了棧空間了  分配到了buf裏面了




定位分配可以在棧空間,也可以在全局空間
不能再代碼區分配空間


只有在堆空間分配需要delete
C++中的new/delete會調用構造和析構函數


3,C++ new/delete 會調用malloc和free
new.cpp


#include<iostream>
using namespace std;


class Sample{
  int x;
  Sample(){cout << "Sample()" << endl;}
  ~Sample(){cout << "~Sample()" << endl;}
  void show(){cout <<"x=" << x << endl;}
};


int main(){
  Sample* s = new Sample;
  s->x = 100;
  s->show();
  delete s;  


  Sample* s2 = (Sample*)malloc(sizeof(Sample));
  s2->x = 200;
  s2->show();
  free(s2);


  Sample* s3 = new Sample[5];//構造和析構調用五次
  delete[] s3;


  Sample s5[5];//會構造五個對象出來,是在棧裏面的分配的
  //棧中是自動的分配和釋放
  return 0;
}


4,C語言中是malloc和free


5,unix規範  sbrk/brk


6,Linux分配  mmap


7,系統調用(內核)  kmalloc  vmalloc


get_free_page() 獲取空閒的內存頁面


四,進程空間
1,程序:在磁盤上保存的可以運行的文件
開始從PATH找,找到後讀取到內存中
2,進程:正在運行的程序,存在內存中


memory.c


#include<stdio.h>


int main(){
  int x = 100;  
  printf("x=%d\n",x);
  return 0;
}


執行a.out的時候,先按照PATH從磁盤上找,找到後讀到內存
代碼讀取到內存中存放的位置叫代碼區(code)


代碼區(code)


全局區


BSS段


棧區(stack)


堆區(heap)




3,一個進程空間被劃分爲一下部分:
1)代碼區:要執行的程序被放入此區,只讀區域
從08048000開始
2)全局區:保存全局變量,全局變量在main函數執行之前分配
3)BSS段:保存未初始化的全局變量,BSS段在main函數執行之前會被
清零。全局區和BSS段可稱爲全局區,靜態區,數據區等


全局變量未被初始化是0,局部是垃圾數據,隨機的
4)棧區:保存局部變量(包括函數參數),內存分配和釋放自動進行的
棧中的變量也稱爲自動變量
5)堆區:也叫自由區,分配new,malloc分配出來的內存空間。
空間的分配和釋放由程序員決定的。




ps -ef | grep a.out


cd /proc/4778




全局初始化的在全局區
全局未賦值的在BSS
全局常量在代碼區
函數參數和局部變量在棧區
靜態局部變量在全局區
局部常量在棧區
局部整形指針在堆區
局部字符指針在代碼區
局部字符數組在棧中




char.c
#include<stdio.h>
#include<string.h>


int main(){
  char* str1 = "abcdef";//str1四個字節,在棧裏面,保存的內容在代碼區中
  str1[0] = 'A';//段錯誤,代碼區是隻讀區域,不能更改的
  printf("str1=%p\n",str1);
  
  str1 = "ABCDEF";//正確,改變的是str1的值,改變的是棧,而不是代碼區




  char str2[] = "abcdef";
  str2[0] = 'A';
  return 0;


}


%s後面要的是地址


=======================================================
????????????????????
char* str1="abcdef";
printf("str1=%c\n",*str1);
=========================================================
stack.c
#include<stdio.h>
#include<string.h>
void fa(){
  int x;//自動變量,在棧中分配的4Byes的空間
  x = 100;
  x = "abc";
  printf("x=%s\n",x);
  strcpy(&x,"abc");//正確
  strcpy(&x,"abcdef");//錯誤
  printf("x=%x\n",x);
  printf("&x=%s\n",&x);
}


int main(){


  fa();
  return 0;
}


注:代碼區只讀,不能改
棧區的數據很特別,內存,存數據,類型,const等等僅僅是讓編譯器看的









發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章