linux下c语言网络实验遇到的问题(1)

来源:互联网 发布:大数据平台性能指标 编辑:程序博客网 时间:2024/05/16 15:48

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.


原创粉丝点击