积极答复者
malloc 第二次开辟内存时提示堆被损坏

问题
-
下面是部分源码
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日 11:16
答案
-
刘政华你好
欢迎来到MSDN论坛。
我不知道你说的“c与c++学习实验系统”是什么,我感觉可能那个系统偏重於检查有无编码语法错误,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
全部回复
-
刘政华你好
欢迎来到MSDN论坛。
我不知道你说的“c与c++学习实验系统”是什么,我感觉可能那个系统偏重於检查有无编码语法错误,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