目录
[1. 柔性数组](#1. 柔性数组)
书接上文,动态内存管理,
题目4
大家来思考一下
void Test(void)
{
char *str = (char *) malloc(100);
strcpy(str, "hello");
free(str);
if(str != NULL)
{
strcpy(str, "world");
printf(str);
}
}
你掌握了吗?
#include <stdio.h>
#include <stdlib.h>
#include<string.h>
void Test(void)
{
char* str = (char*)malloc(100);
strcpy(str, "hello");//这里的str拷贝了一份hello 的地址,
free(str);//str被释放后成为野指针
if (str != NULL) // ok
{
strcpy(str, "world");// 把str还给操作系统了无法继续使用打印出来hello和world越界访问
printf(str);
}
}
int main()
{
Test();
return 0;
}
正确的应该在free后面加上str为NULL 就不会出现越界访问的问题
void Test(void)
{
char* str = (char*)malloc(100);
strcpy(str, "hello");//这里的str拷贝了一份hello 的地址,
free(str);//提前释放这块空间不属于str了
str = NULL;
if (str != NULL) // ok
{
strcpy(str, "world");// 打印出来hello和world越界访问 ,
printf(str);
}
}
1. 柔性数组
也许你从来没有听说过柔性数组(flexible array)这个概念,但是它确实是存在的。 C99 中,结构中的最后⼀个元素允许是未知⼤⼩的数组,这就叫做『柔性数组』成员
struct arr
{
int a;
char c;
int b[];//没有定义大小的成员叫柔性数组成员,只限定于最后一个
};
用malloc 实现柔性数组
struct arr
{
int a;
char c;
int arr[];//没有定义大小的成员叫柔性数组成员
};
int main()
{
struct arr* S= (struct arr *) malloc(sizeof(struct arr) + 20 * sizeof(int));
if (S == NULL)
{
perror("malloc()");
return 1;
}
//使用空间
S->a = 100;
int i = 0;
for(i = 0; i < 20; i++)
{
S->arr[i] = i + 1;
}
//调整空间大小
struct arr*ptr =(struct arr *) realloc(S, sizeof(struct arr) + 40 * sizeof(int));
if (ptr != NULL)
{
S = ptr;
ptr = NULL;
}
else
{
return 0;
}
for (i = 0; i < 40; i++)
{
printf("%d ", S->arr[i]);
}
free(S);
S = NULL;
return 0;
前20个数字打印后,后20个字节打印随机值。
好处是:⽅便内存释放
拓展阅读
2.总结C/C++中程序内存区域划分
前面的内存函数中讲到 存在内存的分配空间,当然内存不只有 栈区、堆区、静态区、上面的就只是在语言的内存大概的剖析,当然到了Linux 系统中就不一样了。
C/C++程序内存分配的⼏个区域:
1. 栈区(stack):在执⾏函数时,函数内局部变量的存储单元都可以在栈上创建,函数执⾏结束时 这些存储单元⾃动被释放。栈内存分配运算内置于处理器的指令集中,效率很⾼,但是分配的内 存容量有限。 栈区主要存放运⾏函数⽽分配的局部变量、函数参数、返回数据、返回地址等。 《函数栈帧的创建和销毁》
2. 堆区(heap):⼀般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。分配 式类似于链表。
3. 数据段(静态区):(static)存放全局变量、静态数据。程序结束后由系统释放。
**4. 代码段:**存放函数体(类成员函数和全局函数)的⼆进制代码。