免费注册 查看新帖 |

Chinaunix

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

time怎么会篡改内存呢?! [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-04-21 12:08 |只看该作者 |倒序浏览
我写的一个简单的时钟管理的程序,使用SIGALRM信号,其中用到了time函数。刚开始运行总是出新segment error,我gdb调试之后发现,原来是在执行完time函数之后,我之前malloc出来的一块内存被篡改了,所以报了段错误。我把time函数注释掉之后程序就正常了。所以我非常不解,为什么这个time会篡改内存呢?!还是我的程序写的有问题?!

代码贴在下面,希望帮小弟看看。小弟是个菜鸟,希望大侠指教。
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <signal.h>

  5. typedef void (* tm_hdlr)(void* data);

  6. struct listnode {
  7.     unsigned int time;
  8.     tm_hdlr handler;
  9.     void* data;
  10.     struct listnode* next;
  11. };

  12. typedef struct listnode* list;

  13. struct listnode* mknode(list* ls, unsigned int time, tm_hdlr handler, void* data)
  14. {
  15.     if (ls == NULL)
  16.         return NULL;
  17.    
  18.     struct listnode* tmp = (struct listnode*) malloc(sizeof(struct listnode));
  19.     if (tmp == NULL)
  20.         return NULL;
  21.     tmp->time = time;
  22.     tmp->handler = handler;
  23.     tmp->data = data;
  24.     tmp->next = NULL;

  25.     if (*ls == NULL)
  26.     {
  27.         *ls = tmp;
  28.         return tmp;
  29.     }
  30.     //list cur = *ls, prev;
  31.     struct listnode* head = *ls;
  32.     printf("head time [%d]\n", head->time);
  33.     struct listnode* cur = head;
  34.     struct listnode* prev = head;
  35.     for (; cur != NULL && cur->time < time;)
  36.     {
  37.         prev = cur;
  38.         cur = cur->next;
  39.     }

  40.     if (cur == prev)
  41.     {//insert head
  42.         tmp->next = cur;
  43.         *ls = tmp;
  44.     } else {
  45.         tmp->next = prev->next;
  46.         prev->next = tmp;
  47.     }

  48.     return tmp;
  49. }

  50. struct listnode* pollnode(list* ls)
  51. {
  52.     if (ls == NULL || *ls == NULL)
  53.         return NULL;
  54.     struct listnode* tmp = *ls;
  55.     *ls = (*ls)->next;
  56.     return tmp;
  57. }

  58. void rmnode(struct listnode* node)
  59. {
  60.     free(node);
  61. }

  62. void rmlist(list* ls)
  63. {
  64.     list head = *ls;
  65.     struct listnode* tmp = NULL;
  66.     while (NULL != head)
  67.     {
  68.         tmp = head;
  69.         head = head->next;
  70.         rmnode(tmp);
  71.     }
  72.     *ls = NULL;
  73. }

  74. void testlist()
  75. {
  76.     list ls = NULL;
  77.     mknode(&ls, 10, NULL, NULL);
  78.     mknode(&ls, 3, NULL, NULL);
  79.     mknode(&ls, 8, NULL, NULL);
  80.     mknode(&ls, 5, NULL, NULL);
  81.     mknode(&ls, 1, NULL, NULL);
  82.     struct listnode* node = pollnode(&ls);
  83.     rmnode(node);
  84.     node = pollnode(&ls);
  85.     rmnode(node);
  86.     node = pollnode(&ls);
  87.     rmnode(node);
  88.     rmlist(&ls);
  89. }

  90. struct tm_mgr {
  91.     list tm_list;
  92.     struct sigaction tm_osa;
  93. };


  94. void th0(void* data)
  95. {
  96.     printf("th0");
  97. }

  98. static struct tm_mgr* g_tm = NULL;

  99. void sig_alrm(int signum)
  100. {
  101.     if (g_tm == NULL)
  102.         perror("G_TM == NULL");
  103.     printf("sig_alrm\n");
  104.     if (g_tm->tm_list == NULL)
  105.     {
  106.         printf("IT'S SHOULD NOT BE THIS, THERE IS SOMETHING WRONG!\n");
  107.         return ;
  108.     }
  109.     struct listnode* tmp = pollnode(&(g_tm->tm_list));
  110.     list ls = g_tm->tm_list;
  111.     if (ls == NULL)
  112.     {
  113.         printf("NO NEXT TIME!\n");
  114.         return ;
  115.     }
  116.     //set next one.
  117.     //int now = time();
  118.     int now = 0;
  119.     int firetime = ls->time - now;
  120.     alarm(firetime);
  121. }

  122. struct tm_mgr* init_tm()
  123. {
  124.     struct tm_mgr* tm = (struct tm_mgr*) malloc(sizeof(struct tm_mgr));
  125.     printf("struct tm_mgr size [%d]\n", sizeof(struct tm_mgr));
  126.     tm->tm_list = NULL;
  127.     struct sigaction sa;
  128.     sa.sa_flags = 0;
  129.     sigemptyset(&sa.sa_mask);
  130.     sa.sa_handler = sig_alrm;
  131.     if (-1 == sigaction(SIGALRM, &sa, &(tm->tm_osa)))
  132.         return NULL;
  133.     g_tm = tm;
  134.     return tm;
  135.     //static struct tm_mgr tm;
  136.     //tm.tm_list = NULL;
  137.     //struct sigaction sa;
  138.     //sa.sa_flags = 0;
  139.     //sigemptyset(&sa.sa_mask);
  140.     //sa.sa_handler = sig_alrm;
  141.     //if (-1 == sigaction(SIGALRM, &sa, &(tm.tm_osa)))
  142.         //return NULL;
  143.     //g_tm = &tm;
  144.     //return &tm;
  145. }

  146. void reg_timer(struct tm_mgr* tm, unsigned int seconds, tm_hdlr handler, void* data)
  147. {
  148.     if (tm == NULL)
  149.         return ;

  150.     //PROB!!!!
  151.     //int now = time();
  152.     int now = 0;
  153.     int fire = now + seconds;
  154.     struct listnode* node = mknode(&(tm->tm_list), fire, handler, data);
  155.     list ls = tm->tm_list;
  156.     if (node == ls)
  157.     {//insert at first.        
  158.         alarm(seconds);
  159.     }
  160. }

  161. //void begin_timer(struct tm_mgr* tm)
  162. //{
  163.    
  164. //}

  165. void term_tm(struct tm_mgr* tm)
  166. {
  167.     if (-1 == sigaction(SIGALRM, &(tm->tm_osa), NULL))
  168.         return ;
  169.     if (tm != NULL)
  170.     {
  171.         rmlist(&(tm->tm_list));
  172.         free(tm);
  173.     }
  174.     g_tm = NULL;
  175. }

  176. void sig_int(int signum)
  177. {
  178.     reg_timer(g_tm, 1, th0, (void*)0);
  179. }

  180. int main()
  181. {
  182.     //testlist();

  183.     if (SIG_ERR == signal(SIGINT, sig_int))
  184.         perror("SIGNAL");

  185.     struct tm_mgr *tm = init_tm();
  186.     reg_timer(tm, 1, th0, (void*)0);
  187.     reg_timer(tm, 2, th0, (void*)1);
  188.     reg_timer(tm, 3, th0, (void*)2);

  189.     //begin_timer(tm);

  190.     for (;;)
  191.         pause();

  192.     term_tm(tm);
  193.     return 0;
  194. }
复制代码

论坛徽章:
0
2 [报告]
发表于 2012-04-21 13:05 |只看该作者
我刚才发现了一个我编程上的错误,我需要获取当前时间。原型是:
time_t time(time_t *t);//time.h
我没有加参数NULL,换成time(NULL)之后程序正常,但是还是不知道为什么time()这个普通的函数会修改内存呢?!

论坛徽章:
0
3 [报告]
发表于 2012-04-21 17:10 |只看该作者
只能说这是你操作不当引起的,标准用法本来就需要加参数,你不按标准来使用出现的错误根据编译器的不同可能会有所不同,函数调用跳转前参数一般都是先push进栈的,在执行时直接pop栈得到参数,你这个由于没有参数就没有参数入栈,但time函数执行时从栈里获取参数,修改了栈内容,同时获取的是某个不确定的值,操作以这个值为内存地址的内存会导致段错误是很正常的

论坛徽章:
0
4 [报告]
发表于 2012-04-22 00:43 |只看该作者
chnliyong 发表于 2012-04-21 17:10
只能说这是你操作不当引起的,标准用法本来就需要加参数,你不按标准来使用出现的错误根据编译器的不同可能 ...

恩,我觉得你说的有道理。不过被篡改的内存是malloc出来的,在堆上呀。

论坛徽章:
0
5 [报告]
发表于 2012-04-22 13:17 |只看该作者
回复 3# chnliyong

噢,的确是你说的那样,把tm_mgr*当作了time_t*然后向指向的内存写时间,因为指针指向的是堆内存,所以写到了堆上。
谢谢!
   

论坛徽章:
13
15-16赛季CBA联赛之同曦
日期:2016-01-28 19:52:032015亚冠之北京国安
日期:2015-10-07 14:28:19NBA常规赛纪念章
日期:2015-05-04 22:32:03处女座
日期:2015-01-15 19:45:44卯兔
日期:2014-10-28 16:17:14白羊座
日期:2014-05-24 15:10:46寅虎
日期:2014-05-10 09:50:35白羊座
日期:2014-03-12 20:52:17午马
日期:2014-03-01 08:37:27射手座
日期:2014-02-19 19:26:54子鼠
日期:2013-11-30 09:03:56狮子座
日期:2013-09-08 08:37:52
6 [报告]
发表于 2012-04-22 15:26 |只看该作者
向大家学习,看看应该怎么解决!
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP