msmtp配置

2014年10月06日 21:54

http://www.docin.com/p-471069369.html

虚函数内存占用

2014年8月28日 18:00

#include <iostream>

using namespace std;

class A
{
    int a;
    virtual void f();
};

class B
{
    int b;
    virtual void f();
    virtual void g();
};

class C:public A,public B
{
    int c;
    virtual void h();
};


class D:virtual public A
{
    int d;
    virtual void k();
};

class E:public A
{
    int e;
    virtual void k();
};

int main()
{
    cout << sizeof(A)
    << " "
    << sizeof(B)
    << " "
    << sizeof(C)
    << " "
    << sizeof(D)
    << " "
    << sizeof(E)
    << endl;
    return 0;
}

运行结果:8 8 20 16 12

可见g++对虚拟继承采用的是Pointer Strategy所产生的数据布局,如果采用Virtual Table Offset Strategy所产生的数据布局将会是8 8 20 12 12(详见《深度探索C++对象模型》P121-123)。

将数据以位制显示

2014年7月17日 21:32

 #include <stdio.h>

 
typedef unsigned char *byte_pointer;
 
void show_bytes(byte_pointer start, int len)
{
    int i;
    for(i=0; i<len; ++i)
    {
        printf("%.2x   ", start[i]);
    }
    printf("\n");
}
 
void show_int(int *x)
{
    //void *p;
    show_bytes((byte_pointer)x, sizeof("0123"));
}
 
int main()
{
    int j = 4;
    //show_int(j);
    show_int(&j);
    return 0;
}
 

应该记住的话

2014年7月03日 02:40

1.虽然栈是从高地址向低地址增长的,但数组总是从低地址向高地址排列的
2.void* 不能指向由const修饰的变量
3.如果一个指针变量被delete释放后,确保其被赋值为NULL,防止此指针变量变成野指针
4.绝对不能把一个整型值赋值给一个指针变量
5.不能对void*指针进行算术操作
6.禁止返回局部变量的地址或引用
7.一种有效解决数组溢出的方法:即通过数组最后一个元素自行决定数组是否结束
8.重复包含头文件有以下问题:
     1)使预处理的速度变慢了,要处理很多本来不需要处理的头文件
     2)如果有foo.h 包含bar.h ,bar.h 又包含foo.h 的情况,预处理器就陷入死循环了(其实编
译器都会规定一个包含层数的上限)
     3)头文件里有些代码不允许重复出现,虽然变量和函数允许多次声明(只要不是多次定义
就行),但头文件里有些代码是不允许多次出现的,比如typedef类型定义和结构体Tag定义
等,在一个程序文件中只允许出现一次
9.gcc中 int a; 为暂时定义,可与 int a = 2; 同时并存,而 g++ 貌似是定义,不允许 int a; 出现,报错重复定义了
10.如果提供了一个复制构造函数,编译器就不再生成默认构造函数了,所以当定义复制构造函数时,一定要定义构造函数

const引用的一个迷惑性问题

2014年6月22日 19:58

int a = 1;

int &b = a; // 正确

--------------------------------------  

int &c = 1; // 错误

const int &c = 1; // 正确

--------------------------------------

int& max(int &a, int &b) {return a>b?a:b;}

max(1,2); // 竟然编译正确?--->是不正确的(已解决),调用了库函数的max,将其改为imax试试

--------------------------------------

另外,如果要将函数形参全部声明为const引用,注意函数返回类型若为引用,则定为const

const int& max(const int &a, const int &b) {return a>b?a:b;}

int& max(const int &a, const int &b) {return a>b?a:b;} // 错误

--------------------------------------

int a = 1;

int &b = a; // 无temp产生

--------------------------------------

int a = 1;

const int &b = a; // 无temp产生

--------------------------------------

const int a = 1;

const int &b = a; // 无temp产生

--------------------------------------

double d = 3.14;

int &b = d; // 错误

--------------------------------------

double d =3.14;

const int &b = d; // 产生temp,b绑定在temp临时对象上,并非对象d上

--------------------------------------

const int &i = 1; //产生temp,i绑定在temp临时对象上

 

可达到此目的的有一下几个命令:

1.which-命令的位置,在变量环境PATH中查找

which -a command_name, -a列出所有指令,不加-a只列第一个找到的命令

2.whereis-搜索特定文件

-b,只找binary文件;  -m,只找说明文件; -s,只找source来源文件;  -u,没有说明档的文件

3.locate-输入文件部分名称即可搜索

4.find-不常用,速度慢,很耗硬盘

find [path] [option] [action]

ssh服务

2014年6月10日 16:40

ssh为 secure shell的缩写,其为建立在应用层和传输层基础上的安全协议,是目前较为安全的网络服务程序。

下面主要介绍一下在Ubuntu系统下的安装和加密。

一、安装

联网终端敲进命令

$ sudo apt-get install openssh-server 

系统将自动进行安装,安装完成以后,先启动服务

$ sudo /etc/init.d/ssh start  

$ sudo /etc/init.d/ssh start

启动后,可以通过如下命令查看服务是否正确启动

$ ps -e|grep ssh   

6212 ?        00:00:00 sshd  

$ ps -e|grep ssh 6212 ? 00:00:00 sshd

如上表示启动ok。注意,ssh默认的端口是22,可以更改端口,更改后先stop,然后start就可以了。

更改配置在/etc/ssh/sshd_config下,如下所示。

$ vi /etc/ssh/sshd_config   

# Package generated configuration file

# See the sshd(8) manpage for details

# What ports, IPs and protocols we listen for

Port 22

二、连接

与服务器连接

$ ssh 主机名@IP地址  

文件拷贝
 
$ sudo scp 主机名@IP地址:/文件路径
 
三、加密与无密连接
 
1.client端生成公钥和密钥

 

我们使用RSA密钥认证的目的是:从client端登陆server端时,不需要密码认证。

所以,我们在进行认证时首先需要在client端建立属于client端自己的一对密钥(公钥和私钥),建立方法如下:

在命令行下执行:$ ssh-keygen 

执行过程中,它先要求你确认保存公钥的位置(默认为:.ssh/id_rsa),

然后它会让你重复输入一个密码两次,如果不想在使用公钥的时候输入密码,可以留空

执行完毕后,就会生成数据client端的一对密钥。

 

SSH 密钥默认储存在账户的家目录下的 ~/.ssh 目录中

关键是看有没有用 xxx_rsa 和 xxx_rsa.pub 来命名的一对文件,有 .pub 后缀的文件就是公钥,另一个文件则是密钥。

2.将Client端的公钥添加到用于认证的Server端的公钥文件中

 

首先检查Server端需要认证的phenix用户的家目录下,隐藏目录“ssh”目录下是否存在一个名为“authorized_keys”的文件,

若不存在,使用命令:touch authorized_keys 创建一个空文件

创建完成后,则可以执行如下步骤:

 

执行步骤如下:

1)将Clinet端公钥的内容复制

2)将复制到的Client端公钥内容,粘贴至Server端刚才创建的 authorized_keys 文件中,保存文件。

3)更改 authorized_keys 文件的权限

执行命令:chmod 600  authorized_keys

3.验证无密码登陆

 

在Client端命令行执行如下命令:

ssh -p12  phenix@10.2.31.33     (本例ssh服务开在了12端口,默认为22)

 

直接登陆至Server端,表示验证成功。

注意:

1)ssh-keygen执行完毕后一定要检查下phenix用户家目录下.ssh目录中是否有一对密钥

2)在将公钥粘贴至Server端后,一定要修改authorized_keys文件的权限为600,否则认证会失败

3)Server端需要开启SSH服务,不然客户端使用ssh连接不上

测试is-programmer服务器地点

2014年6月09日 21:41

一直用着is-programmer编写blog,突然发现我提交的文章时间很是怪异(很多都是凌晨几点的)。

原来该网站的服务器不在中国non~~

于是我就查了查:

该文章发表之后看看发表时间

现在北京时间是 Tuesday,10 June 2014  16:41

然后根据世界时间时区表查询即可得知

中国位于东八区(+8)

由发表时间可知,该网站服务器位于西十一区(-11)

潜藏在代码中的Bug

2014年5月28日 22:08

  1 #include <iostream>
  2 #include <string>
  3 #include <cstring>
  4 using namespace std;
  5 
  6 int main()
  7 {
  8     string s = "hello world!";
  9     const char *str = s.c_str();
 10     char ch[100];
 11     int i = 0;
 12     while(*str != '\0')
 13     {
 14         ch[i++] = *str++;
 15     }   
 16     cout << ch << endl;
 17     return 0;
 18 } 
 
 
请将10行中的数组初始化,或者退出while循环后增加语句ch[i] = '\0' 。
另外,可以有:s + ' a' + str + "welcome" + ch 。想想string类的特征。

单链表的逆转

2014年5月15日 21:50

#include <iostream>
using namespace std;
 
void ReverseList(List L)
{
    if(L == NULL)
        return;
    pNode p = L->next;
    L->next = NULL;
    while(p)
    {
        pNode q = p;
        p = p->next;
        q->next = L->next;
        L->next = q;
    }
}