C语言-动态内存管理(三)-题目
最编程
2024-01-02 14:32:14
...
请问运行Test函数会有什么样的结果?
void GetMemory(char *p){
p=(char*) malloc(100);
}
void Test(void){
char *str=NULL;
GetMemory(str);
strcpy(str,"hello world");
printf(str);
}
int main(){
Test();
return 0;
}
结果:
这段代码会崩溃掉,并且存在内存泄漏的问题。
接下来我们分析一下原因:
从main函数出发,调用Test我们进入Test函数,创建了个char类型指针变量str ,然后调用GetMemory,将str传过去,str值为NULL,那么p传入的参数也为NULL,然后执行malloc动态内存分配:
开辟了一段空间首地址为:12ff21cd并返回给p,那么此时p指向了这段空间,到这里GetMemory的程序执行完毕。回到Test,我们会发现p虽然改了但是GetMemory已经结束p生命周期也已经结束了,并没有改变str的值。
所以此时str的值还是NULL。
str的值为NULL,并不是一个有效的地址。从NULL开始拷贝的时候会从这个地址自增,那必然会访问非法空间,那strcpy肯定是执行不成功的。
strcpy(str,"hello world");
所以这里就会直接崩溃。
崩溃的原因:
所以这里的问题还是因为传递的是str的值而不是str的指针。所以并没有改变str的值,如果想要改变str的值那应该传递指向str的指针。应该是个二级指针。
内存泄漏因为:
str以值的形式传递给p,p是GetMemory函数的形式参数,只在函数内部有效,等函数返回之后,动态开辟内存尚未释放,并且无法找到,所以造成内存泄漏。
要改进怎么改进呢?我们需要用到二级指针,将str地址传进去即可。
void GetMemory(char **p){
*p=(char*) malloc(100);
}
void Test(void){
char *str=NULL;
//传递str的地
GetMemory(&str);
strcpy(str,"hello world");
printf(str);
//释放空间
free(str);
str=NULL;
}
int main(){
Test();
return 0;
}
或者:如果不想用二级指针可以把申请好空间的地址返回去
char* GetMemory(char *p){
p=(char*) malloc(100);
return p;
}
void Test(void){
char *str=NULL;
str= GetMemory(str);
strcpy(str,"hello world");
printf(str);
free(str);
str=NULL;
}
int main(){
Test();
return 0;
}
输出结果:
推荐阅读
-
用 C 语言求阶乘之和的三种实现方法(先求阶乘再求加法)
-
C 语言|第三次博客作业
-
三天钓鱼,两天日光浴 - C 语言
-
正负偏差变量 即 d2+、d2- 分别表示决策值中超出和未达到目标值的部分。而 di+、di- 均大于 0 刚性约束和目标约束(柔性目标约束有偏差) 在多目标规划中,>=/<= 在刚性约束中保持不变。当需要将约束条件转换为柔性约束条件时,需要将 >=/<= 更改为 =(因为已经有 d2+、d2- 用来表示正负偏差),并附加上 (+dii-di+) 注意这里是 +di、-di+!之所以是 +di,-di+,是因为需要将目标还原为最接近的原始刚性约束条件 优先级因素和权重因素 对多个目标进行优先排序和优先排序 目标规划的目标函数 是所有偏差变量的加权和。值得注意的是,这个加权和都取最小值。而 di+ 和 dii- 并不一定要出现在每个不同的需求层次中。具体分析需要具体问题具体分析 下面是一个例子: 题目中说设备 B 既要求充分利用,又要求尽可能不加班,那么列出的时间计量表达式即为:min z = P3 (d3- + d3 +) 使用 + 而不是 -d3 + 的原因是:正负偏差不可能同时存在,必须有 di+di=0 (因为判定值不可能同时大于目标值和小于目标值),而前面是 min,所以只要取 + 并让 di+ 和 dii- 都为正值即可。因此,得出以下规则: 最后,给出示例和相应的解法: 问题:某企业生产 A 和 B 两种产品,需要使用 A、B、C 三种设备。下表显示了与工时和设备使用限制有关的产品利润率。问该企业应如何组织生产以实现下列目标? (1) 力争利润目标不低于 1 500 美元; (2) 考虑到市场需求,A、B 两种产品的生产比例应尽量保持在 1:2; (3)设备 A 是贵重设备,严禁超时使用; (4)设备 C 可以适当加班,但要控制;设备 B 要求充分利用,但尽量不加班。 从重要性来看,设备 B 的重要性是设备 C 的三倍。 建立相应的目标规划模型并求解。 解:设企业生产 A、B 两种产品的件数分别为 x1、x2,并建立相应的目标计划模型: 以下为顺序求解法,利用 LINGO 求解: 1 级目标: 模型。 设置。 variable/1..2/:x;! s_con_num/1...4/:g,dplus,dminus;!所需软约束数量(g=dplus=dminus 数量)及相关参数; s_con(s_con_num);! s_con(s_con_num,variable):c;!软约束系数; 结束集 数据。 g=1500 0 16 15. c=200 300 2 -1 4 0 0 5; 结束数据 min=dminus(1);!第一个目标函数;!对应于 min=z 的第一小部分;! 2*x(1)+2*x(2)<12;!硬约束 @for(s_con_num(i):@sum(variable(j):c(i,j)*x(j))+dminus(i)-dplus(i)=g(i)); !使用设置完成的数据构建软约束表达式; ! !软约束表达式 @for(variable:@gin(x)); !将变量约束为整数; ! 结束 此时,第一级目标的最优值为 0,第一级偏差为 0: 第二级目标: !求 dminus(1)=0,然后求解第二级目标。 模型。 设置。 变量/1..2/:x;!设置:变量/1..2/:x; ! s_con_num/1...4/:g,dplus,dminus;!软约束数量及相关参数; s_con(s_con_num(s_con_num));! s_con(s_con_num,variable):c;! 软约束系数; s_con(s_con_num,variable):c;! 结束集 数据。 g=1500 0 16 15; c=200 300 2 -1 4 0 0 5; 结束数据 min=dminus(2)+dplus(2);!第二个目标函数 2*x(1)+2*x(2)<12;!硬约束 @for(s_con_num(i):@sum(variable(j):c(i,j)*x(j))+dminus(i)-dplus(i)=g(i)); ! 软约束表达式;! dminus(1)=0; !第一个目标结果 @for(variable:@gin(x)); ! 结束 此时,第二个目标的最优值为 0,偏差为 0: 第三目标 !求 dminus(2)=0,然后求解第三个目标。 模型。 设置。 变量/1..2/:x;!设置:变量/1..2/:x; ! s_con_num/1...4/:g,dplus,dminus;!软约束数量及相关参数; s_con(s_con_num(s_con_num));! s_con(s_con_num,variable):c;! 软约束系数; s_con(s_con_num,variable):c;! 结束集 数据。 g=1500 0 16 15; c=200 300 2 -1 4 0 0 5; 结束数据 min=3*dminus(3)+3*dplus(3)+dminus(4);!第三个目标函数。 2*x(1)+2*x(2)<12;!硬约束 @for(s_con_num(i):@sum(variable(j):c(i,j)*x(j))+dminus(i)-dplus(i)=g(i)); ! 软约束表达式;! dminus(1)=0; !第一个目标约束条件; ! dminus(2)+dplus(2)=0; !第二个目标约束条件 @for(variable:@gin(x));! 结束 最终结果为 x1=2,x2=4,dplus(1)=100,最优利润为
-
10 万字的 C 语言入门手册,历时三个月,详尽的 C 语言教程终于面世,给你全新的 C 语言入门体验!
-
探索 C 内存:动态内存管理详解
-
C 语言版冒泡排序算法详解 - 三、C 程序的冒泡排序算法
-
C 语言真的很难?那是因为你没有看这张图,没有通过化整为零的方式轻松学习 C 语言。-三、scanf
-
C 语言基础(三角形面积、阶乘算法、sqrt、pow 函数、海伦公式、get、getchar、scanf 之间的区别、字符转换、增长率计算、分支和循环结构编程)
-
C 语言丨运算符号 & 的三种用法(附示例代码)