数据结构实践——初始化顺序表怎么就内存溢出了?

简介:   有学生调程序,是要建顺序表。   他的程序是这样的:#include <stdio.h>#include <malloc.h>#define MaxSize 50 //Maxsize将用于后面定义存储空间的大小typedef int ElemType; //ElemType在不同场合可以根据问题的需要确定,在此取简单的in

  有学生调程序,是要建顺序表。
  他的程序是这样的:

#include <stdio.h>
#include <malloc.h>

#define MaxSize 50    //Maxsize将用于后面定义存储空间的大小
typedef int ElemType;  //ElemType在不同场合可以根据问题的需要确定,在此取简单的int
typedef struct
{
    ElemType data[MaxSize];  //利用了前面MaxSize和ElemType的定义
    int length;
} SqList;

//声明自定义函数
SqList InitList(SqList *L);   //初始化顺序表
void ListInsert(SqList *L,int i,int b);  //插入函数
void DispList(SqList *L);    //输出函数
bool ListEmpty(SqList *L);//判定是否为空表ListEmpty(L)

int main()
{
    SqList *sq;
    InitList(sq);
    ListInsert(sq, 1, 5);
    ListInsert(sq, 2, 3);
    ListInsert(sq, 1, 4);
    DispList(sq);
    return 0;
}

//输出线性表DispList(L)
void DispList(SqList *L)
{
    int i;
    if (ListEmpty(L))
        return;
    for (i=0; i<L->length; i++)
        printf("%d ",L->data[i]);
    printf("\n");
}

//判定是否为空表ListEmpty(L)
bool ListEmpty(SqList *L)
{
    return(L->length==0);
}

//初始化顺序表InitList(*L)
SqList InitList(SqList *L)
{
    L=(SqList *)malloc(sizeof(SqList));//这里申请了结点空间
    L->length=0;
    return *L;
}

void ListInsert(SqList *L,int i,int b)   //插入函数
{
    int j,k;

    if(i<1)
    {
        printf("插入位置非法/n");
    }
    for(j=L->length; j>i; j--)
    {
        L->data[j]=L->data[j-1];
    }
    L->data[i]=b;
    L->length++;
}

  运行结果是这样的:
这里写图片描述
  他找我帮忙。基本可以断定,内存使用不当,有溢出。
  看一下编译提示的信息,有一个警告:
  D:\CB\DS\main.cpp|21|warning: ‘sq’ is used uninitialized in this function [-Wuninitialized]|
  说在21行,sq未经初始化就使用了。通俗的说法,野指针。
  围绕着sq找。在main()函数中有:

    SqList *sq;
    InitList(sq);

  这里在调用InitList时,实际参数sq就是野指针。但这还不是出问题的关键,看InitList函数的定义是:

//初始化顺序表InitList(*L)
SqList InitList(SqList *L)
{
    L=(SqList *)malloc(sizeof(SqList));//这里申请了结点空间
    L->length=0;
    return *L;
}

  调用时,L得到的是野指针,但在函数里为其分配空间了。但调用完,这个地址并未返回到main函数中。调用完InitList,sq仍然还是野指针。这是关键!
  沿这个思路,希望能将分配的空间地址能返回给main函数。return *L就不合适了,return L是返回地址。于是,函数定义改为:

//初始化顺序表InitList(*L)
SqList *InitList(SqList *L)
{
    L=(SqList *)malloc(sizeof(SqList));//这里申请了结点空间
    L->length=0;
    return L;
}

  既然参数SqList *L调用时给的是个野指针,不要也罢。于是改选成无参函数:

//初始化顺序表InitList(*L)
SqList *InitList()
{
    SqList *L=(SqList *)malloc(sizeof(SqList));//这里申请了结点空间
    L->length=0;
    return L;
}

  在调用时,main函数定义为:

int main()
{
    SqList *sq;
    sq = InitList();
    ListInsert(sq, 1, 5);
    ListInsert(sq, 2, 3);
    ListInsert(sq, 1, 4);
    DispList(sq);
    return 0;
}

  为保证程序能够正确编译,函数声明等处的语法问题不一一列出。解决了这一环节的问题,程序能够运行了,但结果:
  这里写图片描述
  断定问题出在ListInsert函数中。看调用,插入的位置用的是逻辑序(从1开始记数),但函数定义中,直接L->data[i]=b;没有考虑物理存储中,下标是从0开始的。
  所以,在ListInsert中加入一个 i–,完成逻辑序号向物理序号的转换,Done。
  正确的结果不贴图了,最后改过的程序是:

#include <stdio.h>
#include <malloc.h>

#define MaxSize 50    //Maxsize将用于后面定义存储空间的大小
typedef int ElemType;  //ElemType在不同场合可以根据问题的需要确定,在此取简单的int
typedef struct
{
    ElemType data[MaxSize];  //利用了前面MaxSize和ElemType的定义
    int length;
} SqList;

//声明自定义函数
SqList *InitList();   //初始化顺序表
void ListInsert(SqList *L,int i,int b);  //插入函数
void DispList(SqList *L);    //输出函数
bool ListEmpty(SqList *L);//判定是否为空表ListEmpty(L)

int main()
{
    SqList *sq;
    sq = InitList();
    ListInsert(sq, 1, 5);
    ListInsert(sq, 2, 3);
    ListInsert(sq, 1, 4);
    DispList(sq);
    return 0;
}

//输出线性表DispList(L)
void DispList(SqList *L)
{
    int i;
    if (ListEmpty(L))
        return;
    for (i=0; i<L->length; i++)
        printf("%d ",L->data[i]);
    printf("\n");
}

//判定是否为空表ListEmpty(L)
bool ListEmpty(SqList *L)
{
    return(L->length==0);
}

//初始化顺序表InitList(*L)
SqList *InitList()
{
    SqList *L=(SqList *)malloc(sizeof(SqList));//这里申请了结点空间
    L->length=0;
    return L;
}

void ListInsert(SqList *L,int i,int b)   //插入函数
{
    int j;

    if(i<1)
    {
        printf("插入位置非法/n");
    }
    i--;
    for(j=L->length; j>i; j--)
    {
        L->data[j]=L->data[j-1];
    }
    L->data[i]=b;
    L->length++;
}
目录
相关文章
|
9天前
|
存储 算法 C语言
通义灵码在考研C语言和数据结构中的应用实践 1-5
通义灵码在考研C语言和数据结构中的应用实践,体验通义灵码的强大思路。《趣学C语言和数据结构100例》精选了五个经典问题及其解决方案,包括求最大公约数和最小公倍数、统计字符类型、求特殊数列和、计算阶乘和双阶乘、以及求斐波那契数列的前20项和。通过这些实例,帮助读者掌握C语言的基本语法和常用算法,提升编程能力。
|
16天前
|
存储 编译器 C语言
数据结构-顺序表详解(看这篇就足够了,哈哈哈)
数据结构-顺序表详解(看这篇就足够了,哈哈哈)
46 2
|
22天前
简化数据结构的初始化过程
简化数据结构的初始化过程
37 0
|
18天前
|
存储 Java
数据结构第二篇【关于java线性表(顺序表)的基本操作】
数据结构第二篇【关于java线性表(顺序表)的基本操作】
27 6
|
18天前
|
存储 安全 Java
【用Java学习数据结构系列】探索顺序表和链表的无尽秘密(附带练习唔)pro
【用Java学习数据结构系列】探索顺序表和链表的无尽秘密(附带练习唔)pro
20 3
|
18天前
|
存储 C语言
探索C语言数据结构:利用顺序表完成通讯录的实现
本文介绍了如何使用C语言中的顺序表数据结构实现一个简单的通讯录,包括初始化、添加、删除、查找和保存联系人信息的操作,以及自定义结构体用于存储联系人详细信息。
18 2
|
21天前
|
存储 算法 索引
【数据结构】——顺序表
【数据结构】——顺序表
|
21天前
|
存储
【数据结构】线性表和顺序表
【数据结构】线性表和顺序表
19 1
|
22天前
|
存储
数据结构1——顺序表
数据结构1——顺序表
17 1
|
11天前
|
存储
数据结构(顺序表)
数据结构(顺序表)
17 0