none
malloc 第二次开辟内存时提示堆被损坏 RRS feed

  • 问题

  • 下面是部分源码

    int main(){
     DATA_THIS=new_link();
     if(DATA_THIS==NULL)
      exit(1);
     init_link_data();
     return 0;
    }

    void init_link_data()//学生表数据
    {
     DATA *tmp[3];
     int i;
     NODE *p;
     for(i=0;i<3;i++){
      tmp[i]=(DATA*)malloc(sizeof(DATA));
     }
     strcpy(tmp[0]->sno,"s001");
     tmp[0]->age=11;
     strcpy(tmp[1]->sno,"s002");
     tmp[1]->age=22;
     strcpy(tmp[2]->sno,"s003");
     tmp[2]->age=33;
     for(i=0;i<3;i++)
      link_insert_rear(DATA_THIS,tmp[i],sizeof(DATA));//第二次循环进入的时候就出问题了
     p=DATA_THIS->head->next;
     while(p!=DATA_THIS->last){
      printf("%s %d\n",((DATA*)(p->data))->sno,((DATA*)(p->data))->age);
      p=p->next;
     }
    }

    void link_insert_rear(LINK *THIS,void *data,int size){
     NODE *p=NULL;
     p=(NODE*)malloc(sizeof(NODE));//第二次运行到这里就失败了。
     if(p==NULL)
      return;
     p->data=(void *)malloc(sizeof(size));
     if(p->data==NULL){
      free(p);
      return;
     }
     //将外部传入的数据拷贝到指定的p->data里面
     memcpy(p->data,data,size);
     p->prev=THIS->last->prev;
     p->next=THIS->last;
     THIS->last->prev->next=p;
     THIS->last->prev=p;
     THIS->count++;
    }

    下面是程序的所有代码

    /*
    通用链表的建立
    为非循环双向链表
    */

    //DATA类型的结构体,具体的结构替换此处以及后面的com接口函数即可
    typedef struct StudentInfo{
     char sno[21];
     int age;
    }DATA;

    #include <stdio.h>
    #include <stdlib.h>
    #include <ctype.h>
    #include <string.h>
    typedef struct node{
     void *data;//节点中的数据域
     struct node *prev;//前向指针
     struct node *next;//后向指针
    }NODE;

    typedef struct LINKLIST
    {
     node *head;//整个链表的头指针
     node *last;//整个链表的尾指针
     int count;//链表结点数目
    }LINK;

    LINK *DATA_THIS=NULL;

    LINK *new_link(){
     LINK *link=NULL;
     link =(LINK *)malloc(sizeof(LINK));
     if(link==NULL)  //如果没有开辟到空间,那么退出
      return link;//失败话link=NULL ,即为return NULL
     link->head=(NODE*)malloc(sizeof(NODE));
     link->last=(NODE*)malloc(sizeof(NODE));
     if(link->head==NULL||link->last==NULL)
     {
      free(link);
      return NULL;
     }
     //开辟成功空间后
     link->head->prev=NULL;
     link->last->next=NULL;
     link->head->next=link->last;
     link->last->prev=link->head;
     link->count=0;
     return link;
    }

    //向尾部插入size大小的数据大小
    void link_insert_rear(LINK *THIS,void *data,int size){
     NODE *p=NULL;
     p=(NODE*)malloc(sizeof(NODE));
     if(p==NULL)
      return;
     p->data=(void *)malloc(sizeof(size));
     if(p->data==NULL){
      free(p);
      return;
     }
     //将外部传入的数据拷贝到指定的p->data里面
     memcpy(p->data,data,size);
     p->prev=THIS->last->prev;
     p->next=THIS->last;
     THIS->last->prev->next=p;
     THIS->last->prev=p;
     THIS->count++;
    }

    //通过结点编号获取结点
    NODE *link_get_node_by_index(LINK *THIS,int index){
     NODE *p=THIS->head->next;
     int tmp=0;
     if(THIS==NULL||THIS->count==0||index>THIS->count)
      return NULL;
     while(p!=THIS->last)
     {
      tmp++;
      if(tmp==index)
       return p;//找到后返回对应的结点的指针
      p=p->next;
     }
     return NULL;//遍历完了还没找到,则返回NULL
    }

    //比较学号,实际比较是,此函数当做参数传入link_node_by_key的第三个参数中
    int com_sno(void *data,void *sno2){
     DATA *p=(DATA*)data;
     if(strcmp(p->sno,(char*)sno2)==0)
      return 1;
     else
      return 0;
    }

    //比较age,年龄。此函数当做参数传入link_node_by_key的第三个参数中
    int com_age(void *data,void *age){
     DATA *p=(DATA*) data;
     if(p->age==*((int *)age))
      return 1;
     else
      return 0;
    }
    //根据关键字key,并通过一定的比较算法com获取链表中的结点。
    NODE *link_get_node_by_key(LINK *THIS,void *key,int (*com)(void *p1,void *p2)){
     NODE *p=THIS->head->next;
     if(THIS==NULL||THIS->count==NULL||key==NULL)
      return NULL;
     while(p!=THIS->last){
      if(com(p->data,key)){
       break;
      }
      p=p->next;
     }
     return p;
    }

    //通过关键字去删除结点
    int link_del_node_by_key(LINK *THIS,void *key,int (*com)(void *data,void *key)){
     NODE *p,*temp=THIS->head->next;
     while(p!=THIS->last){
      if(com(temp->data,key)){
       p=temp;//记下找到的节点,用于后面去释放
       temp->prev->next=temp->next;
       temp->next->prev=temp->prev;
       THIS->count--;
       free(p);
       return 1;
      }
      temp=temp->next;
     }
     return 0;//循环查找完后仍没有找到,返回0.即没有此关键字对应的结点可供删除
    }

    //通过索引编号删除结点
    int link_del_node_by_index(LINK *THIS,int index){
     NODE *p=link_get_node_by_index(THIS,index);
     NODE *temp;
     if(p==NULL)
      return 0;//没找到结点
     temp=p;
     p->prev->next=p->next;
     p->next->prev=p->prev;
     THIS->count--;
     free(temp);
     return 1;
    }

    //删除所有的数据结点,但是保留头尾结点
    int link_del_all_data(LINK *THIS){
     NODE* temp,*p=THIS->head->next;
     if(THIS==NULL||THIS->count==0)
      return 0;
     while(p!=THIS->last){
      temp=p;
      p=p->next;
      free(temp->data);
      free(temp);
     }
     THIS->head->next=THIS->last;
     THIS->last->prev=THIS->head;
     THIS->count=0;
     return 1;
    }

    //删除链表头尾指针
    int link_del_all(LINK **THIS){
     link_del_all_data(*THIS);
     free((*THIS)->head);
     free((*THIS)->last);
     free(*THIS);
     *THIS=NULL;
     return 1;
    }

    void init_link_data()//学生表数据
    {
     DATA *tmp[3];
     int i;
     NODE *p;
     for(i=0;i<3;i++){
      tmp[i]=(DATA*)malloc(sizeof(DATA));
     }
     strcpy(tmp[0]->sno,"s001");
     tmp[0]->age=11;
     strcpy(tmp[1]->sno,"s002");
     tmp[1]->age=22;
     strcpy(tmp[2]->sno,"s003");
     tmp[2]->age=33;
     for(i=0;i<3;i++)
      link_insert_rear(DATA_THIS,tmp[i],sizeof(DATA));
     p=DATA_THIS->head->next;
     while(p!=DATA_THIS->last){
      printf("%s %d\n",((DATA*)(p->data))->sno,((DATA*)(p->data))->age);
      p=p->next;
     }
    }
    int main(){
     DATA_THIS=new_link();
     if(DATA_THIS==NULL)
      exit(1);
     init_link_data();
     return 0;
    }


    I will stay away with you for the sky died.

    在c与c++学习实验系统里运行没任何错误,vs2010下提示错误,请问到底是什么原因
    2012年7月10日 10:29

答案

  • 刘政你好

    欢迎来到MSDN论坛。

    我不知道你说的“cc++学习实验系统”是什么,我感觉可能那个系统偏重於检查有无编码语法错误,Visual Studio可能更全面一些。

    根据您的代码,我发现您的link_insert_rear函数中在传入sizeof(DATA)后,没有为链表数据部分分配正确大小,从而导致内存分配溢出。

    请修改:

    p->data=(void *)malloc(sizeof(size)); //是“size”的大小?还是“DATA”的大小?

    ->

     p->data=(void *)malloc(size);

    希望对您有帮助。

    此致


    Elegentin Xie [MSFT]
    MSDN Community Support | Feedback to us

    • 已标记为答案 刘政华 2012年7月11日 6:46
    2012年7月11日 6:40
    版主

全部回复

  • 刘政你好

    欢迎来到MSDN论坛。

    我不知道你说的“cc++学习实验系统”是什么,我感觉可能那个系统偏重於检查有无编码语法错误,Visual Studio可能更全面一些。

    根据您的代码,我发现您的link_insert_rear函数中在传入sizeof(DATA)后,没有为链表数据部分分配正确大小,从而导致内存分配溢出。

    请修改:

    p->data=(void *)malloc(sizeof(size)); //是“size”的大小?还是“DATA”的大小?

    ->

     p->data=(void *)malloc(size);

    希望对您有帮助。

    此致


    Elegentin Xie [MSFT]
    MSDN Community Support | Feedback to us

    • 已标记为答案 刘政华 2012年7月11日 6:46
    2012年7月11日 6:40
    版主
  • 非常感谢,那里写错了,size已经就是DATA结构体的大小,我却又用了sizeof求了次,导致分配的内存不足


    I will stay away with you for the sky died.

    2012年7月11日 6:45