LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 765|回复: 7

关于指针的问题

[复制链接]
发表于 2004-8-26 17:00:25 | 显示全部楼层 |阅读模式
我的代码如下:

#include <stdio.h>
#include <malloc.h>
struct sqlist
{
        int *base;
        int size;
        int length;
};
void init(struct sqlist *L);
void insert(struct sqlist *L,int pos,int e);
void main()
{
        int i,e,n;
        struct sqlist *List=NULL;
        init(List);
        printf("最多输入%d个数\n",List->size);
        printf("输入数据(遇到零则结束):\n");

        scanf("%d",&e);
        while(e!=0)
        {
                List->base[list->length]=e;
                List->length++;
                if(List->length>=List->size)
                {
                        printf("it is enugh\n");
                        break;
                }
                scanf("%d",&e);
        }

        printf("请输入插入位置:");
        scanf("%d",&n);
        printf("请输入插入数据:");
        scanf("%d",&e);

        printf("\n插入前,数据为:");
        for(i=0;i<List->length;i++)
                printf("%d\t ",List->base);
        printf("\n");
       
        insert(List,n,e);

        printf("插入后,数据为:");
        for(i=0;i<List->length;i++)
                printf("%d\t ",List->base);
        printf("\n");

        free(List->base);
}

void init(struct sqlist *L)
{
        L->base=(int *)malloc(10*sizeof(int));
        L->length=0;
        L->size=10;
}
void insert(struct sqlist *L,int pos,int e)
{
        int *newbase,i;
        if(pos<=0||pos>L->length+1)
        {
                printf("下标错误!\n");
                return;
        }
        if(L->length==L->size)
        {
                newbase=(int *)malloc((L->size+2)*sizeof(int));
                for(i=0;i<L->length;i++)
                        newbase=L->base;
                L->size+=2;
                free(L->base);
                L->base=newbase;
        }

        for(i=L->length-1;i>=pos-1;i--)
                L->base[i+1]=L->base;
        L->base[pos-1]=e;
        L->length++;
}

编译通过了,可运行的时候却出现内存溢出错误。
不解!困惑中!~~~~~~~~~~~~~~~:confused:
望高手指教。3x
发表于 2004-8-26 17:11:52 | 显示全部楼层
你把NULL传到init里面,不出错才怪
发表于 2004-8-27 02:08:24 | 显示全部楼层

  1. int main()
  2. {
  3.     int i,e,n;
  4.     [color=red]struct sqlist sql;
  5.     struct sqlist *List = &sql;[/color]
  6.     init(List);
  7. ...
  8. void init(struct sqlist *L)
  9. {
  10.     L->base=(int *)malloc(10*sizeof(int));
  11.     L->length=0;
  12.     L->size=10;
  13. }
复制代码


考虑到 init 函数的实现,在给 init 函数传递顺序列表指针时,应该使该指针指向一个实际存在的列表结构体,而不是空指针。
发表于 2004-8-27 20:40:39 | 显示全部楼层
此程序不按惯例编写,如果是初学者自然很容易出错。

按照大家所熟悉的,通常会定义init()函数应返回列表的首元素的指针,定义为struct sqlist *init(struct sqlist *L);

如果L是列首且未为空则为其分配内存空间并返回(这与lucifer的不能将NULL指针传到函数里的说法不一致),因为init()函数的功能就应该能够为第一个元素分配空间;当然如果它不为空的话说明已经存在而不用再分配了。山河水可能是理解有误,他并没有为首元素(L)分配空间!!!  在指针L(即列首指针)仍不能保证有效时却去分配L->base的空间,这显然是本末倒置了。只要纠正过来就不会有什么问题了,也就不用象quanliking提到的那样预先定义列首的空间,从而完全符合全程动态分配内存空间的要求了。

这只是我个人理解,与楼上两位虽有不同,但不防继续探讨。
发表于 2004-8-27 22:20:47 | 显示全部楼层
我对上述分析有异议:
首先,L 并非列首,它是指向结构体(struct) sqlist 类型的一个局部指针变量,而所传入的结构体 sql 严格的讲不属于顺序列表内部,而是列表的一个很重要的辅助成份,指明了列表的属性,如大小 size 和 长度 length,以及列表的入口(即存储位置) base 指针。
所以我认为搂主提到的“也就不用象quanliking提到的那样预先定义列首的空间“这样的讲法不够准确。这里我所定义的结构体 sql,并非是为列首分配空间,上面已经解释过,而具体分配空间是由 init 函数中的 malloc 函数来完成的。

其次,struct sqlist sql; 是局部变量,它的作用域范围应该在 main 函数体内,而不应该是在 init 函数体内定义,否则从 init 函数返回后,局部变量 sql 就会被销毁或产生其它类型的错误。

以上是我的观点,可能有偏驳。

为了讲的更清楚,我把搂主的设计思路用图来表示一下:


  1.             struct sqlist sql
  2.                _________        __________________
  3.       L --->  |   base  | ---> |   |   |   |   |    ......
  4.               |---------|      |___|___|___|___|__
  5.               |   size  |      
  6.               |---------|
  7.               |  length |
  8.               |_________|   
复制代码
 楼主| 发表于 2004-8-28 10:57:20 | 显示全部楼层
本人受益匪浅,谢谢!~~~~~~~~~~
发表于 2004-8-30 04:05:38 | 显示全部楼层
呵呵,都有道理啊
不过
其次,struct sqlist sql; 是局部变量,它的作用域范围应该在 main 函数体内,而不应该是在 init 函数体内定义,否则从 init 函数返回后,局部变量 sql 就会被销毁或产生其它类型的错误。
这个嘛,完全可以用malloc分配一个struct返回啊
发表于 2004-8-30 09:47:31 | 显示全部楼层
如果在函数中动态分配内存,那么最好还是专门写一个函数用来释放。
btw,这个时候需要声明的就是void (struct sqlist **L)了。这个可千万不要搞错。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表