Category Archives: c c++

内存分配方式

内存分配方式有三种:
(1) 从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量,static 变量。
(2) 在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。(不要用return 语句返回指向“栈内存”的指针,因为该内存在函数结束时自动消亡)

char *GetString(void)
{
char p[] = “hello world”;
return p; // 编译器将提出警告
}

void Test4(void)
{
char *str = NULL;
str = GetString(); // str 的内容是垃圾
cout<< str << endl;
}

下面这种方式可以避免这种情况:

char *GetString2(void)
{
char *p = “hello world”;
return p;
}
void Test5(void)
{
char *str = NULL;
str = GetString2();
cout<< str << endl;
}

但这种设计概念却是错误的。因为GetString2 内的“hello world”是常量字符串,位于静态存储区,它在程序生命期内恒定不变。无论什么时候调用GetString2,它返回的始终是同一个“只读”的内存块。
(3) 从堆上分配,亦称动态内存分配。程序在运行的时候用malloc 或new 申请任意多少的内存,程序员自己负责在何时用free 或delete 释放内存。动态内存的生存期由我们决定,使用非常灵活,但问题也最多。

引用与指针的比较

引用和指针的区别在于下面几点:

1. 创建引用时必须初始化,而且不能初始化为null;  而指针可以不初始化,也可以初始化为null

int &a; //error, references must be initialized
int *p; //right
int &a = NULL; //error, can’t init as NULL
int *p = NULL; //right

2. 引用初始化后,就不再改变; 而指针随时可以改变所指的对象。

int a = 1;
int b = 2;
int &r = a; //r成为a的引用,即别名,r恒为a 的引用,不可改变
r = b;//此时不要以为r变成了b的引用,而是把b的值赋给了a, 此是a, r 都为b的值2
r = 3;//a, r的值都变成了3,b的值不变,仍为2

指针却是可以随时改变所指的对象

int a = 1;
int b = 2;
int *p = &a; // *p == 1, p初始化成了a的地址值
p = &b; // *p == 2,p地址值变了,p变成了b的地址值

sizeof

c语言里的sizeof 是一个计算数据存储空间大小的单目运算符,它返回数据所占的字节个数, 我们可以先来看看MSND里的定义:

sizeof Operator
sizeof expression

The sizeof keyword gives the amount of storage, in bytes, associated with a variable or a type (including aggregate types). This keyword returns a value of type size_t.
The expression is either an identifier or a type-cast expression (a type specifier enclosed in parentheses).

When applied to a structure type or variable, sizeof returns the actual size, which may include padding bytes inserted for alignment.
When applied to a statically dimensioned array, sizeof returns the size of the entire array. The sizeof operator cannot return the size of
dynamically allocated arrays or external arrays

这段话大概讲的就是:

1:sizeof运算符可以得到变量和类型存储空间的大小,大小是以字节为单位的,如一个变量a所占的空间是2个字节,那么sizeof(a) == 2。

2:如果a是一个数据类型,那么必须加括号表示为sizeof(a)形式,如果a是变量sizeof a也是可以的,但通常都写成sizeof(a)形式。

3:当sizeof 应用于结构体或变量时,它返回实际所占的空间大小,这个空间可能包括编绎器为了内存对齐而插入的额外的字节。

4:当sizeof应用于静态多维数组时,它返回整个数据的大小,但sizeof 不能应用于对态分配的数组。

下面举例说明sizeof的运用

1. 用于类型

sizeof(int) //返回4,表示整形数占4个字节,其实这个与系统有关, 一般linux和32位windows都返回4;

sizeof(char) //返回1;

struct student {
int age;
char name[20];
};
sizeof(student);// 返回24;

struct student {
int age;
char sex;
};
sizeof(student);// 返回8, 这里为什么会返回8呢,一个int占4个字节, 一个char占一个字节, 应该是5个字节啊, 其实不这样的, 编绎器为了更高效率而使得内存对齐, 为char sex另外插入了3个字节, 所以返回8;

2. 用于变量

int a = 100;

sizeof(a);//返回4, 一般根据它的类型而决定它所占空间大小

long float f = 33.00;

sizeof(f );//返回8,

char *p;

sizeof(p );//返回4, 这里p是一个指针变量,sizeof(p)返回这个指针变量所占的空间大小, 而不是字符p所占的空间大小(一个字符只占一个字节)。

3. 用于数组

int int_arr[5];
sizeof(int_arr);//返回20, 而不是5,当用于数组时, 它返回这个数组所点的总字节数, 而不是数组无素的个数;