备案 增加网站,表单插件wordpress,盗版视频网站怎么做的,做企业网站域名需要解析吗上篇文章我介绍了介绍动态内存管理 的相关内容#xff1a;c语言进阶部分详解#xff08;详细解析动态内存管理#xff09;-CSDN博客
各种源码大家可以去我的github主页进行查找#xff1a;唔姆/比特学习过程2 (gitee.com)
今天便接“上回书所言”#xff0c;来介绍《高质…上篇文章我介绍了介绍动态内存管理 的相关内容c语言进阶部分详解详细解析动态内存管理-CSDN博客
各种源码大家可以去我的github主页进行查找唔姆/比特学习过程2 (gitee.com)
今天便接“上回书所言”来介绍《高质量C-C编程》经典例题讲解及柔性数组 目录
一.几个经典例题
1.1题目一
注意 改进 1.2问题二
1.3问题三
1.4问题四
二.柔性数组
2.1柔性数组特点
2.2柔性数组的使用
2.3柔性数组的优势 一.几个经典例题
1.1题目一
void ToMalloc(char* p)
{p (char*)malloc(100);
}
void test1(void)
{char* str NULL;ToMalloc(str);strcpy(str, hello);printf(str);//就是printf(%s,str);free(str);strNULL;
}
int main()
{test1();return 0;
}
运行结果是程序崩溃了 对一个NULL进行解引用操作想对一个指针内容更改必然有解引用操作p动态开辟后没有进行free内存泄露了 注意
有些读者可能遇到这样的情况
int main()
{char* ar abdldsaf;strcpy(ar,hello);printf(ar);return 0;
}
编译器都会报错这是因为ar其实是一个字符串常量 我们怎么能对常量进行修改呢应该使用字符数组来存储可修改的字符串 所以我们可以用数组或者动态开辟进行改正问题 改进
void ToMalloc(char** p)
{*p (char*)malloc(100);
}
void test1(void)
{char* str NULL; ToMalloc(str);strcpy(str, hello);printf(str);//就是printf(%s,str);
} 1.2问题二
char* ToMalloc(void)
{char p[] hello world;return p;
}
void test2(void)
{char* str NULL;str ToMalloc();printf(str);
}int main()
{test2();return 0;
}
结果 大家可以看到是乱码这是因为我们返回了局部变量的地址。当出了ToMalloc函数后p在栈空间上面被销毁了。此时返回的指针将指向无效的内存内存已经还给操作系统了 1.3问题三
void ToMalloc(char** p, int num)
{*p (char*)malloc(num);
}
void test3(void)
{char* str NULL;ToMalloc(str, 100);strcpy(str, hello);printf(str);
}int main()
{test3();return 0;
}
大家可以看到跟问题一我们改进后的代码几乎是是一样的 ,也确实输出hello 问题便是存在内存泄漏 我们没有对malloc开辟的空间进行free 1.4问题四
void test4()
{char* str (char*)malloc(100);strcpy(str, hello);free(str);if (str ! NULL){strcpy(str, world);printf(str);}
}int main()
{test4();return 0;
}
str已经被释放了str成为了野指针又对野指针进行操作非法访问内存 二.柔性数组 C99 中结构中的最后一个元素允许是未知大小的数组这就叫做『柔性数组』成员 基本形式如下 typedef struct st_type { int i ; int a [ 0 ]; // 柔性数组成员 部分编译器不能识别时换成int a[]; } type_a ; 2.1柔性数组特点 结构中的柔性数组成员前面必须至少一个其他成员sizeof 返回的这种结构大小不包括柔性数组的内存包含柔性数组成员的结构一般使用malloc ()函数进行内存的动态分配并且分配的内存应该大于结构的大小以适应柔性数组的预期大小多的一部分要给柔性数组 typedef struct s
{char a;int b;int c[0];//柔性数组成员
};int main()
{printf(%d, sizeof(struct s));return 0;
} 2.2柔性数组的使用
struct s
{char a;int b;int c[0];//柔性数组成员
};int main()
{struct s* s1 (struct s*)malloc(sizeof(struct s)20);if (s1 NULL){perror(malloc);return 1;}//赋值s1-a a;s1-b 6;for (int i 0; i 5; i){s1-c[i] i;}//打印for (int i 0; i 5; i){printf(%d ,s1-c[i]);}//如果不够就扩容struct s* s2 (struct s*)realloc(s1, sizeof(struct s) 40);if (s1 ! NULL){s1 s2;}else{return 1;}//释放free(s1);s1 NULL;return 0;
}
2.3柔性数组的优势 也许我们会想下面的代码也有相同的作用啊为什么还要用柔性数组呢
struct S
{char a;int b;int* c;
};int main()
{struct S* s1 (struct s*)malloc(sizeof(struct s));if (s1 NULL){perror(malloc);return 1;}//赋值s1-a a;s1-b 6;s1-c (int*)malloc(20);for (int i 0; i 5; i){s1-c[i] i;}//打印for (int i 0; i 5; i){printf(%d , s1-c[i]);}//如果不够就扩容int p (struct s*)realloc(s1-c,40);if (s1 ! NULL){s1-c p; }else{return 1;}//释放free(s1-c); //先释放后部分如果先释放前面的就找不到后面的了s1-c NULL;free(s1);s1 NULL;return 0;
}
我们可以知道还是柔性数组的代码更好 优点一方便内存释放 如果结构体里面做了二次内存分配有时可能只针对结构体进行一次释放这样就造成内存泄漏了。 如果我们把结构体的内存以及其成员要的内存一次性分配好了并返回给用户一个结构体指针用户做 一次free 就可以把所有的内存也给释放掉 优点二 这样有利于访问速度 连续的内存有益于提高访问速度也有益于减少内存碎片 好嘞这次的内容就先到这里了感谢大家支持