免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2324 | 回复: 7
打印 上一主题 下一主题

[C] C专家编程中的问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-01-01 23:34 |只看该作者 |倒序浏览
5可用积分
下面的代码主要的功能是利用realloc函数动态分配内存空间。
现在要求
1。在add函数中增加几条语句,使它可以负责动态内存区域的初始内存分配,这是什么意思?怎么作呢?
2。另要求用setjmp/longjmp来优雅的处理内存增长过程中出现的错误,主要的问题是会出现哪些错误?出现了错误longjmp跳转到的位置也就是setjmp的地方设置在哪比较合适?
详细见c专家编程chap10----10.7节


  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>

  4. int             current = 0;
  5. int             total = 10;
  6. char*           dynamic;
  7. static void add(char c);

  8. int main(void)
  9. {
  10.         int             i;
  11.         char            c = 'a';

  12.         dynamic = (char* )malloc(total);//初始空间大小为10个字节
  13.         for(i = 0; i < 26; i++){
  14.                 add(c);
  15.                 c++;
  16.         }

  17.         for(i = 0; i < 26; i++){
  18.                 printf("%c\t", dynamic[i]);
  19.         }//输出结果
  20.         printf("\n");

  21.         exit(0);
  22. }

  23. static void add(char c)
  24. {
  25.         char*           temp = NULL;

  26.         if(current == total - 1){
  27.                 total *= 2;
  28.                 temp = (char* )realloc(dynamic, total);
  29.                 if(temp == NULL){
  30.                         perror("realloc error");
  31.                         exit(1);
  32.                 }
  33.                 else{
  34.                         dynamic = temp;
  35.                 }
  36.         }//空间不够时候用realloc重新分配空间,因为realloc调用事失败会返回NULL,所以将realloc的返回值先赋值给temp
  37.         else{
  38.                 dynamic[current] = c;
  39.                 current++;
  40.         }
  41. }
复制代码

[ 本帖最后由 xiaozhu2007 于 2008-1-1 23:37 编辑 ]

最佳答案

查看完整内容

第一个问题,不是使用flag标志,而是判断dynamic是否为空,如果为空,则分配内存进行初始化。第二个就把setjmp设置在第一个for循环前面吧。

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
2 [报告]
发表于 2008-01-01 23:34 |只看该作者
第一个问题,不是使用flag标志,
而是判断dynamic是否为空,如果为空,
则分配内存进行初始化。
第二个就把setjmp设置在第一个for循环前面吧。

论坛徽章:
0
3 [报告]
发表于 2008-01-01 23:45 |只看该作者
先说要求1吧,它的意思我理解的就是初始化分配操作要求在add()里进行,所以这里就用了一个全局变量flag(0:表示初始化分配完毕,1:未初始化分配)
程序如下,就是在第一次执行add的时候初始化dynamic
要求2怎么做呢?

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>

  4. int             current = 0;
  5. int             total = 10;
  6. char*           dynamic = NULL;
  7. static void add(char c);

  8. int             flag = 0;

  9. int main(void)
  10. {
  11.         int             i;
  12.         char            c = 'a';

  13.         for(i = 0; i < 26; i++){
  14.                 add(c);
  15.                 c++;
  16.         }

  17.         for(i = 0; i < 26; i++){
  18.                 printf("%c\t", dynamic[i]);
  19.         }
  20.         printf("\n");

  21.         exit(0);
  22. }

  23. static void add(char c)
  24. {
  25.         char*           temp = NULL;

  26.         if(flag == 0){
  27.                 temp = (char* )malloc(total);
  28.                 if(temp == NULL){
  29.                         perror("malloc error");
  30.                         exit(1);
  31.                 }
  32.                 else{
  33.                         dynamic = temp;
  34.                 }
  35.                 flag = 1;
  36.         }

  37.         if(current == total - 1){
  38.                 total *= 2;
  39.                 temp = (char* )realloc(dynamic, total);
  40.                 if(temp == NULL){
  41.                         perror("realloc error");
  42.                         exit(2);
  43.                 }
  44.                 else{
  45.                         dynamic = temp;
  46.                 }
  47.         }
  48.         else{
  49.                 dynamic[current] = c;
  50.                 current++;
  51.         }
  52. }
复制代码

论坛徽章:
0
4 [报告]
发表于 2008-01-02 13:02 |只看该作者
这样修改了行不?还有什么地方可以改进的吗?
比如指针的释放???

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <setjmp.h>

  5. int             current = 0;
  6. int             total = 10;
  7. char*           dynamic = NULL;
  8. static jmp_buf  jmp;
  9. static void add(char c);

  10. int main(void)
  11. {
  12.         int             i;
  13.         char            c = 'a';

  14.         for(i = 0; i < 26; i++){
  15.                 add(c);
  16.                 c++;
  17.         }

  18.         if(setjmp(jmp) != 0){
  19.                 printf("memory distribution error\n");
  20.                 exit(1);
  21.         }
  22.         for(i = 0; i < 26; i++){
  23.                 printf("%c\t", dynamic[i]);
  24.         }
  25.         printf("\n");

  26.         exit(0);
  27. }

  28. static void add(char c)
  29. {
  30.         char*           temp = NULL;

  31.         if(dynamic == NULL){
  32.                 temp = (char* )malloc(total);
  33.                 if(temp == NULL){
  34.                         longjmp(jmp, 1);
  35.                 }
  36.                 else{
  37.                         dynamic = temp;
  38.                 }
  39.         }

  40.         if(current == total - 1){
  41.                 total *= 2;
  42.                 temp = (char* )realloc(dynamic, total);
  43.                 if(temp == NULL){
  44.                         longjmp(jmp, 2);
  45.                 }
  46.                 else{
  47.                         dynamic = temp;
  48.                 }
  49.         }
  50.         else{
  51.                 dynamic[current] = c;
  52.                 current++;
  53.         }
  54. }
复制代码

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
5 [报告]
发表于 2008-01-02 13:20 |只看该作者
setjmp位置对吗?
如果真的出错了,能否跳过去?

论坛徽章:
0
6 [报告]
发表于 2008-01-02 13:39 |只看该作者

回复 #5 lenovo 的帖子

能吧!当出现错误的时候调用longjmp返回到setjmp,根据错误的不同,返回1或者2,setjmp接收到非0的longjmp返回值,打印内存分配错误,调用exit结束进程,有什么不对的吗?

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
7 [报告]
发表于 2008-01-02 13:44 |只看该作者
原帖由 xiaozhu2007 于 2008-1-2 13:39 发表
能吧!当出现错误的时候调用longjmp返回到setjmp,根据错误的不同,返回1或者2,setjmp接收到非0的longjmp返回值,打印内存分配错误,调用exit结束进程,有什么不对的吗?

当add函数出错时,setjmp执行了吗?

论坛徽章:
0
8 [报告]
发表于 2008-01-02 14:12 |只看该作者

回复 #7 lenovo 的帖子

呵呵是setjmp的位置错了,应该在第一个for循环前。如果放在第一个for 循环后面,则调用longjmp的时候main中的setjmp还没有执行到呢。

[ 本帖最后由 xiaozhu2007 于 2008-1-2 14:15 编辑 ]
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP