1.联合 union
1.1 联合空间的大小
以联合成员中较大的那个成员为准,同时联合的成员地址都为同一地址。
union un
{
char a;
int i;
};
union in
{
char a[5];
int i;
};
int main()
{
union un a;
union in b;
printf("%d\n", sizeof(a));
printf("%d\n", sizeof(b));
return 0;
}
输出结果为4和8;第二个联合,当开辟的最大成员空间不与默认对齐数成倍数时,自动扩展到最大对齐数的倍数,vs的默认对齐数为8,所以结果为8。
2.动态内存开辟
一般的内存空间存储在栈区,而动态开辟的空间存储的堆区。
2.1 malloc
void * malloc (size_t size )
向内存申请一块size字节的连续的空间,开辟成功并返回这块空间的地址,开辟失败返回空指针NULL。
例如开辟一块40字节的内存空间并将其初始化。
int main()
{
int* p = (int*)malloc(10 * sizeof(int));
for (int i = 0;i < 10;i++)
{
*(p + i) = i;
}
for (int i = 0;i < 10;i++)
{
printf("%d ", *(p + i));
}
free(p);
return 0;
}
2.2 calloc
void * calloc(size_t num,size_t size);
向内存申请一块num个size大小的空间,同时初始化这块空间。
int main()
{
int* p = (int*)calloc(10 ,sizeof(int));
for (int i = 0;i < 10;i++)
{
printf("%d ", *(p + i));
}
free(p);
return 0;
}
3. realloc
void * realloc (void * ptr ,size_t size);
当我们发现之前动态开辟的空间太大或者太小,可以利用realloc进行调整。ptr表示要调整的空间的地址,size表示调整后的大小 ,并不是需要调整的大小。
在对最初开辟的空间进行增加时,由于内存中并不一定有足够的空间能够接上原来的空间,例如最初开辟40个字节,需要增加30个字节,但是原空间20个字节后就有其他程序在使用该空间,此时realloc并不会直接增加,而是重新寻找一块70个字节的空间重新开辟,并保留原数据,返回新空间的地址。
int main()
{
int* p = (int*)calloc(10, sizeof(int));
printf(" %p\n", p);
int* ptr = NULL;
ptr = (int *)realloc(p, 10000);
if (ptr != NULL)
{
p = ptr;
}
printf("%p\n", ptr);
free(p);
return 0;
}
4.free
free(void *);
free是对动态开辟的空间进行释放,如果不进行内存释放,将造成严重的内存泄漏。
例如下面的代码。
int main()
{
while (1)
{
malloc(1);
}
return 0;
}