linux下c語言網絡實驗遇到的問題(1)

1.segmentation fault(core dump)

遇到上述錯誤,網上說是內存訪問越界。不管怎麼說指針不簡單啊。

     1.內存訪問越界

a) 由於使用錯誤的下標,導致數組訪問越界

b) 搜索字符串時,依靠字符串結束符來判斷字符串是否結束,但是字符串沒有正常的使用結束符

c) 使用strcpy, strcat, sprintf, strcmp, strcasecmp等字符串操作函數,將目標字符串讀/寫爆。應該使用strncpy, strlcpy, strncat, strlcat, snprintf, strncmp, strncasecmp等函數防止讀寫越界。

2 多線程程序使用了線程不安全的函數。

3 多線程讀寫的數據未加鎖保護。對於會被多個線程同時訪問的全局數據,應該注意加鎖保護,否則很容易造成core dump

4 非法指針

a) 使用空指針

b) 隨意使用指針轉換。一個指向一段內存的指針,除非確定這段內存原先就分配爲某種結構或類型,或者這種結構或類型的數組,否則不要將它轉換爲這種結構或類型的指針,而應該將這段內存拷貝到一個這種結構或類型中,再訪問這個結構或類型。這是因爲如果這段內存的開始地址不是按照這種結構或類型對齊的,那麼訪問它時就很容易因爲bus error而core dump.

5 堆棧溢出.不要使用大的局部變量(因爲局部變量都分配在棧上),這樣容易造成堆棧溢出,破壞系統的棧和堆結構,導致出現莫名其妙的錯誤。

準備有時間好好學習一下c的內存分配和指針。

 

2.使用printf()輸出時,最好帶上"\n"換行符,否則不容易觀察輸出

 

3.c 中的string

好吧,我之前不知道c中沒有string類型,c中string的實現使用char*,使用時加頭文件<string.h>;c++中有標準string庫,使用時加<string>,c和c++都搞混了。

 

4.隨機數

主要有srand()和rand()兩個函數,包含在頭文件<stdlib.h>

srand():void srand ( unsigned int seed );

用法:它需要提供一個種子,這個種子會對應一個隨機數,如果使用相同的種子後面的 rand() 函數會出現一樣的隨機數。爲了防止隨機數每次重複常常使用系統時間來初始化,即使用 time函數來獲得系統時間,它的返回值爲從 00:00:00 GMT, January 1, 1970 到現在所持續的秒數,然後將 time_t型數據轉化爲(unsigned)型再傳給 srand 函數,即: srand((unsigned) time(&t))  還有一個經常用法,即: srand((unsigned) time(NULL)); 直接傳入一個空指針,因爲你的程序中往往並不需要經過參數獲得的 t 數據。srand((int)getpid()); 使用程序的ID (getpid()) 來作爲初始化種子,在同一個程序中這個種子是固定的。

rand():int rand ( void );

產生一個僞隨機數(根據 srand 初始的隨機數種子),範圍爲 0 - RAND_MAX。RAND_MAX 至少爲 32767。可通過取模來產生不同範圍的隨機數,如:

int value = rand() % (MAX + 1 - MIN) + MIN;

 

使用方法:

srand((unsigned)time(NULL));
rtemp = rand() % 40;

隨機獲取[0,40)的整數。

 

5.獲取當前時間,包含在頭文件<time.h>中

time_t now;

struct tm  *target_time;   //實例化tm指針
time ( &now );  //time函數讀取現在的時間(國際標準時間非北京時間),然後傳值給now
target_time = localtime ( &now ); //localtime函數把從time取得的時間now換算成你電腦中的時間(就是你設置的時區)

printf("Local   time   is   %s/n",asctime(target_time)); //asctime函數把時間轉換成字符,通過printf()函數輸出

 

註釋:time_t是一個在time.h中定義好的結構體。而tm結構體的原形如下:

  struct   tm

  {

  int   tm_sec;//seconds   0-61

  int   tm_min;//minutes   1-59

  int   tm_hour;//hours   0-23

  int   tm_mday;//day   of   the   month   1-31

  int   tm_mon;//months   since   jan   0-11  //當前月份要+1

  int   tm_year;//years   距離1900年的年數,當前年份要+1

  int   tm_wday;//days   since   Sunday,   0-6

  int   tm_yday;//days   since   Jan   1,   0-365

  int   tm_isdst;//Daylight   Saving   time   indicator

  };

 

6.gets 和gets ,都是獲取輸入,但兩者是有區別的

原型是char *fgets(char *buf, int bufsize, FILE *stream);
參數:
*buf: 字符型指針,指向將存儲到的數據地址。
bufsize: 整型數據,指明buf指向的字符數組的大小。
*stream: 文件結構體指針,將要讀取的文件流。

從文件或者屏幕讀入數據保存到buf中最多讀取bufsize-1個字符遇到換行符和文件末尾則結束。返回buf,讀取失敗則返回NULL。

注意:fgets會將最後的換行符存儲到buf中。

gets(char *buf);讀取字符到buf中。不會讀取換行符。

 

7.清除屏幕字符的命令和函數:linux下:

命令:clear

函數:system("clear");

 

8.linux c 刪除已輸入字符:

printf("hello\b \b"): 輸出:hell

 

(以下轉載):
printf("\033[47;31mhello world\033[5m");
47是字背景顏色, 31是字體的顏色, hello world是字符串.  後面的\033[5m是控制碼.
顏色代碼:
QUOTE:
字背景顏色範圍: 40--49                  字顏色: 30--39
        40: 黑                          30: 黑
        41: 紅                          31: 紅
        42: 綠                          32: 綠
        43: 黃                          33: 黃
        44: 藍                          34: 藍
        45: 紫                          35: 紫
        46: 深綠                        36: 深綠
        47: 白色                        37: 白色

ANSI控制碼:


QUOTE:
  \033[0m  關閉所有屬性
  \033[1m  設置高亮度
  \03[4m  下劃線
  \033[5m  閃爍
  \033[7m  反顯
  \033[8m  消隱
  \033[30m  --  \033[37m  設置前景色
  \033[40m  --  \033[47m  設置背景色
  \033[nA  光標上移n行
  \03[nB  光標下移n行
  \033[nC  光標右移n行
  \033[nD  光標左移n行
  \033[y;xH設置光標位置
  \033[2J  清屏
  \033[K  清除從光標到行尾的內容
  \033[s  保存光標位置
  \033[u  恢復光標位置
  \033[?25l  隱藏光標
  \33[?25h  顯示光標
這樣, 在某些時候就可以實現動態的輸出.

 

9.

NULL:空指針,沒有分配內存

'\0':字符串結束符

' ':空格

 

NULL: 定義爲0或0L或(void *)0,用於指示一個指針值是空,即什麼都不指;
'\0': 用且只用字符串結束符;
NUL : 0x00,0值字符,可以用於結束ASCII字符串,和'\0'類似,但是在c/c++中沒有定義,如果要使用的話,需要自定義爲 #define NUL '\0';
EOF :通常定義爲-1, 文件結束符標誌,一般是ctrl+z.


發佈了24 篇原創文章 · 獲贊 6 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章