吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1270|回复: 11
收起左侧

[已解决] C 传递指针引起程序异常退出

[复制链接]
ing 发表于 2020-1-29 11:25
本帖最后由 ing 于 2020-1-29 21:20 编辑



如图断点处,为什么这样 enQueue(&q,t) 传递指针会使程序异常?
捕获.PNG


如果改成 &t(或者 t) 就不会异常,但得到的结果不是我想要的,这个结果说明 enQueue() 方法没有生效
捕获1.PNG

捕获5.PNG



修改方法 enQueue 的参数 Tree *t 为 Tree t 后

enQueue(Queue  q,Tree * t) ⇒ enQueue(Queue  q,Tree t)


再将传递给 enQueue 方法的参数 &t 改为 (*t) 程序才正确运行,但这是为什么?我不理解
捕获3.PNG

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

 楼主| ing 发表于 2020-1-29 15:50
我的爱是你 发表于 2020-1-29 12:47
我很奇怪你们都是用的什么编译器?

我vs直接爆出了16个错误无法进行编译。

...我的问题是
如果入队方法是这样 enqueue(Queue ** q,Tree * t)
那么传递给他的参数(Tree)那里必须是 enQueue(..,(*t));
否则程序异常或得不到结果。
但我不理解为什么不能传入 t 而是 *t。
我的爱是你 发表于 2020-1-29 19:42
本帖最后由 我的爱是你 于 2020-1-29 19:43 编辑

抱歉抱歉
脑子有坑了,修改结构体是最愚蠢最愚蠢的做法。。。。
3.jpg

2.jpg
既然给了指针而结构体不需要指针只需要指针内的参数,那么直接取指针值也是一样。。。。修改结构体工作量要上天了!
以下运行结果:↓
1.jpg
改完函数后把这两处改完即可顺利运行。
 楼主| ing 发表于 2020-1-29 11:31
完整代码
#include<stdarg.h>
#include<malloc.h>
#include<stdio.h>

#define MAX_VERTEX_NUM 50
#define VType int
#define InfoType char
typedef enum {false,true} bool;
bool visited[MAX_VERTEX_NUM];

typedef struct
{
    int weight;
    InfoType info;
}Matrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];

typedef struct
{
    VType vertex[MAX_VERTEX_NUM];
    Matrix arcs;
    int arcNum,vertexNum;
}MGraph;

typedef struct Node
{
    VType data;
    struct Node * l_child;
    struct Node * nextSibling;
}*Tree,Node;

typedef struct Queue
{
    //队列中存放的为树结点
    Tree node;
    struct Queue * next;
}Queue;

int locateVertex(MGraph *g, VType vertex)
{
    for (int i = 0; i < g->vertexNum; ++i) {
        if (g->vertex[i] == vertex)
        {
            return i;
        }
    }
    return -1;
}

void createDN(MGraph * g)
{
    g->arcNum = 13;
    g->vertexNum = 13;
//    printf("请输入顶点数据 \n");
//    for (int i = 0; i < g->vertexNum; ++i) {
//        //strtol
//        scanf("%d",&(g->vertex[i]));
//    }
    for (int i = 0; i < g->vertexNum; ++i) {
        //strtol
        g->vertex[i] = i+1;
    }

    for (int k = 0; k < g->vertexNum; ++k) {
        for (int i = 0; i < g->vertexNum; ++i) {
            g->arcs[k][i].weight = 00;
            g->arcs[k][i].info = NULL;
        }
    }
//    printf("请输入弧头和弧尾 \n");
//    for (int j = 0; j < g->vertexNum; ++j) {
//        VType v1,v2;
//        scanf("%d,%d",&v1,&v2);
//        int n = locateVertex(g,v1);
//        int m = locateVertex(g,v2);
//        g->arcs[n][m].weight = 1;
//        g->arcs[m][n].weight = 1;
//    }

    int n = 0, m = 1;
    g->arcs[n][m].weight = 1;
    g->arcs[m][n].weight = 1;
    m = 2;
    g->arcs[n][m].weight = 1;
    g->arcs[m][n].weight = 1;
    m = 5;
    g->arcs[n][m].weight = 1;
    g->arcs[m][n].weight = 1;
    n = 0, m = 11;
    g->arcs[n][m].weight = 1;
    g->arcs[m][n].weight = 1;
    n = 1, m = 12;
    g->arcs[n][m].weight = 1;
    g->arcs[m][n].weight = 1;
    n = 4, m = 2;
    g->arcs[n][m].weight = 1;
    g->arcs[m][n].weight = 1;
    m = 7, n = 6;
    g->arcs[n][m].weight = 1;
    g->arcs[m][n].weight = 1;
    m = 9;
    g->arcs[n][m].weight = 1;
    g->arcs[m][n].weight = 1;
    m = 8;
    g->arcs[n][m].weight = 1;
    g->arcs[m][n].weight = 1;
    n = 7, m = 9;
    g->arcs[n][m].weight = 1;
    g->arcs[m][n].weight = 1;
    n = 11,m=10;
    g->arcs[n][m].weight = 1;
    g->arcs[m][n].weight = 1;
    n=12;
    g->arcs[n][m].weight = 1;
    g->arcs[m][n].weight = 1;
    m=11;
    g->arcs[n][m].weight = 1;
    g->arcs[m][n].weight = 1;

}

void initQueue(Queue ** q)
{
    (*q) = (Queue*)malloc(sizeof(Queue));
    (*q)->next = NULL;
}

void deQueue(Queue ** q,Tree * t)
{
    (*t) = (*q)->next->node;
    (*q)->next = (*q)->next->next;
}

bool isEmpty(Queue * q)
{
    if (q->next)
        return false;
    else
        return true;
}

int firstAdjVex(MGraph * g,int v)
{
    for (int i = 0; i < g->vertexNum; ++i) {
        if (g->arcs[v][i].weight == 1)
        {
            return i;
        }
    }
    return -1;
}

int nextAdjVex(MGraph * g,int v,int w)
{
    for (int i = w+1; i < g->vertexNum; ++i) {
        if (g->arcs[v][i].weight == 1)
        {
            return i;
        }
    }
    return -1;
}

void enQueue(Queue ** q,Tree t)
{
    Queue * e = malloc(sizeof(Queue));
    e->node = t;
    e->next = NULL;
    Queue * temp = (*q);
    while (temp->next)
    {
        temp = temp->next;
    }
    temp->next = e;
}

//Tree t
void bfsTree(MGraph * g,Tree * t)
{
    Queue * q = NULL;
    initQueue(&q);
    //根结点入队
    enQueue(&q, (*t)); // t
    //存储出队列的结点
    Tree p = NULL;
    //while (q)
    while (!isEmpty(q))
    {
        bool first = true;
        deQueue(&q,&p);
        //判断出队结点中的数据在数组中的具体位置
        int v = locateVertex(g,p->data);
        visited[v] = true;
        for (int i = firstAdjVex(g,v); i > -1; i = nextAdjVex(g,v,i)) {
            if (!visited[i])
            {
                Tree temp = malloc(sizeof(Node));
                temp->data = g->vertex[i];
                temp->l_child = NULL;
                temp->nextSibling = NULL;
                enQueue(&q,temp);
                if (first)
                {
                    p->l_child = temp;
                    first = false;
                }
                else
                {
                    p->nextSibling = temp;
                }
                visited[i] = true;
                p = temp;
            }
        }
    }
}

//Tree t
void bfsForest(MGraph * g, Tree * t)
{
    (*t) = NULL;
    Tree q = NULL;
    for (int i = 0; i < g->vertexNum; ++i) {
        visited[i] = false;
    }
    for (int j = 0; j < g->vertexNum; ++j) {
        if (!visited[j])
        {
            Tree p = malloc(sizeof(Node));
            p->data = g->vertex[j];
            p->nextSibling = NULL;
            p->l_child = NULL;
            //如果树为空,则该顶点作为树的树根
            if (!(*t))
            {
                (*t) = p;
            }
            else
            {
                q->nextSibling = p;
            }
            q = p;
            bfsTree(g,t);
        }
    }
}

void preOrderTraverse(Tree t)
{
    if (t)
    {
        printf("%d ",t->data);
        preOrderTraverse(t->l_child);
        preOrderTraverse(t->nextSibling);
    }
}

int main(int argc, char* argv[])
{
    MGraph g;
    createDN(&g);
    Tree t;
    bfsForest(&g,&t);
    preOrderTraverse(t);

    return 0;
}
stardxxx 发表于 2020-1-29 11:42
广搜?
没看懂你问的问题,,
我的爱是你 发表于 2020-1-29 12:47
本帖最后由 我的爱是你 于 2020-1-29 12:49 编辑

我很奇怪你们都是用的什么编译器?

我vs直接爆出了16个错误无法进行编译。

以下是我修改的。


[C] 纯文本查看 复制代码
#include<stdarg.h>
#include<malloc.h>
#include<stdio.h>

#define MAX_VERTEX_NUM 50
#define VType int
#define InfoType char
typedef enum { False, TRUE } boo;
boo visited[MAX_VERTEX_NUM];

typedef struct
{
        int weight;
        InfoType info;
}Matrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];

typedef struct
{
        VType vertex[MAX_VERTEX_NUM];
        Matrix arcs;
        int arcNum, vertexNum;
}MGraph;

typedef struct Node
{
        VType data;
        struct Node* l_child;
        struct Node* nextSibling;
}*Tree, Node;

typedef struct Queue
{
        //队列中存放的为树结点
        Tree node;
        struct Queue* next;
}Queue;

int locateVertex(MGraph* g, VType vertex)
{
        for (int i = 0; i < g->vertexNum; ++i) {
                if (g->vertex[i] == vertex)
                {
                        return i;
                }
        }
        return -1;
}

void createDN(MGraph* g)
{
        g->arcNum = 13;
        g->vertexNum = 13;
        //    printf("请输入顶点数据 \n");
        //    for (int i = 0; i < g->vertexNum; ++i) {
        //        //strtol
        //        scanf("%d",&(g->vertex[i]));
        //    }
        for (int i = 0; i < g->vertexNum; ++i) {
                //strtol
                g->vertex[i] = i + 1;
        }

        for (int k = 0; k < g->vertexNum; ++k) {
                for (int i = 0; i < g->vertexNum; ++i) {
                        g->arcs[k][i].weight = 00;
                        g->arcs[k][i].info = NULL;
                }
        }
        //    printf("请输入弧头和弧尾 \n");
        //    for (int j = 0; j < g->vertexNum; ++j) {
        //        VType v1,v2;
        //        scanf("%d,%d",&v1,&v2);
        //        int n = locateVertex(g,v1);
        //        int m = locateVertex(g,v2);
        //        g->arcs[n][m].weight = 1;
        //        g->arcs[m][n].weight = 1;
        //    }

        int n = 0, m = 1;
        g->arcs[n][m].weight = 1;
        g->arcs[m][n].weight = 1;
        m = 2;
        g->arcs[n][m].weight = 1;
        g->arcs[m][n].weight = 1;
        m = 5;
        g->arcs[n][m].weight = 1;
        g->arcs[m][n].weight = 1;
        n = 0, m = 11;
        g->arcs[n][m].weight = 1;
        g->arcs[m][n].weight = 1;
        n = 1, m = 12;
        g->arcs[n][m].weight = 1;
        g->arcs[m][n].weight = 1;
        n = 4, m = 2;
        g->arcs[n][m].weight = 1;
        g->arcs[m][n].weight = 1;
        m = 7, n = 6;
        g->arcs[n][m].weight = 1;
        g->arcs[m][n].weight = 1;
        m = 9;
        g->arcs[n][m].weight = 1;
        g->arcs[m][n].weight = 1;
        m = 8;
        g->arcs[n][m].weight = 1;
        g->arcs[m][n].weight = 1;
        n = 7, m = 9;
        g->arcs[n][m].weight = 1;
        g->arcs[m][n].weight = 1;
        n = 11, m = 10;
        g->arcs[n][m].weight = 1;
        g->arcs[m][n].weight = 1;
        n = 12;
        g->arcs[n][m].weight = 1;
        g->arcs[m][n].weight = 1;
        m = 11;
        g->arcs[n][m].weight = 1;
        g->arcs[m][n].weight = 1;

}

void initQueue(Queue** q)
{
        (*q) = (Queue*)malloc(sizeof(Queue));
        (*q)->next = NULL;
}

void deQueue(Queue** q, Tree* t)
{
        (*t) = (*q)->next->node;
        (*q)->next = (*q)->next->next;
}

boo isEmpty(Queue* q)
{
        if (q->next)
                return False;
        else
                return TRUE;
}

int firstAdjVex(MGraph* g, int v)
{
        for (int i = 0; i < g->vertexNum; ++i) {
                if (g->arcs[v][i].weight == 1)
                {
                        return i;
                }
        }
        return -1;
}

int nextAdjVex(MGraph* g, int v, int w)
{
        for (int i = w + 1; i < g->vertexNum; ++i) {
                if (g->arcs[v][i].weight == 1)
                {
                        return i;
                }
        }
        return -1;
}

void enQueue(Queue** q, Tree t)
{
        Queue* e = (struct Queue*)malloc(sizeof(Queue));
        e->node = t;
        e->next = NULL;
        Queue* temp = (*q);
        while (temp->next)
        {
                temp = temp->next;
        }
        temp->next = e;
}

//Tree t
void bfsTree(MGraph* g, Tree* t)
{
        Queue* q = NULL;
        initQueue(&q);
        //根结点入队
        enQueue(&q, (*t)); // t
        //存储出队列的结点
        Tree p = NULL;
        //while (q)
        while (!isEmpty(q))
        {
                boo first = TRUE;
                deQueue(&q, &p);
                //判断出队结点中的数据在数组中的具体位置
                int v = locateVertex(g, p->data);
                visited[v] = TRUE;
                for (int i = firstAdjVex(g, v); i > -1; i = nextAdjVex(g, v, i)) {
                        if (!visited[i])
                        {
                                Tree temp = (struct Node*)malloc(sizeof(Node));
                                temp->data = g->vertex[i];
                                temp->l_child = NULL;
                                temp->nextSibling = NULL;
                                enQueue(&q, temp);
                                if (first)
                                {
                                        p->l_child = temp;
                                        first = False;
                                }
                                else
                                {
                                        p->nextSibling = temp;
                                }
                                visited[i] = TRUE;
                                p = temp;
                        }
                }
        }
}

//Tree t
void bfsForest(MGraph* g, Tree* t)
{
        (*t) = NULL;
        Tree q = NULL;
        for (int i = 0; i < g->vertexNum; ++i) {
                visited[i] = False;
        }
        for (int j = 0; j < g->vertexNum; ++j) {
                if (!visited[j])
                {
                        Tree p = (struct Node*)malloc(sizeof(Node));
                        p->data = g->vertex[j];
                        p->nextSibling = NULL;
                        p->l_child = NULL;
                        //如果树为空,则该顶点作为树的树根
                        if (!(*t))
                        {
                                (*t) = p;
                        }
                        else
                        {
                                q->nextSibling = p;
                        }
                        q = p;
                        bfsTree(g, t);
                }
        }
}

void preOrderTraverse(Tree t)
{
        if (t)
        {
                printf("%d ", t->data);
                preOrderTraverse(t->l_child);
                preOrderTraverse(t->nextSibling);
        }
}

int main(int argc, char* argv[])
{
        MGraph g;
        createDN(&g);
        Tree t;
        bfsForest(&g, &t);
        preOrderTraverse(t);

        return 0;
}



1.PNG
这个是楼主想要的结果?

2.jpg
你这个malloc怎么可以不定义返回的结构指针!

31.jpg
还有你这个宏为啥直接能用bool命名。。

我进行了以上修改就没有任何问题了。lz的错误在于语法问题。


 楼主| ing 发表于 2020-1-29 15:58
本帖最后由 ing 于 2020-1-29 16:09 编辑
我的爱是你 发表于 2020-1-29 12:47
我很奇怪你们都是用的什么编译器?

我vs直接爆出了16个错误无法进行编译。

我用Clion,VS跑程序会出错我都不知道是什么原因。。
我在Clion定义返回的结构指针是这样的形式 (Queue*) ,没有struct
后来发现不写也不影响,就懒得写了我不知道这是必须的
你这是C++吧?因为后缀不是 .c;
然后 bool 功能是要自己实现的。。  

最后,能加我吗?我不知道怎么玩 VS,在Clion可运行的代码放VS就异常
我的爱是你 发表于 2020-1-29 17:19
ing 发表于 2020-1-29 15:58
我用Clion,VS跑程序会出错我都不知道是什么原因。。
我在Clion定义返回的结构指针是这样的形式 (Queue* ...

我这是c ,cpp只不过是新建文件懒得改了。
void返回理论可以是任何返回,但规范来说malloc为你申请了一篇内存域 ,你理应按照语法返回指针为该申请的结构类型。
另外我知道bool被你重定义为枚举类型,但我没记错的话bool变量在编译器内已经使用typedef进行过宏定义,你这不亚于用int重定义char类型 命名是不规范的。
我的爱是你 发表于 2020-1-29 17:50
本帖最后由 我的爱是你 于 2020-1-29 18:19 编辑
ing 发表于 2020-1-29 15:50
...我的问题是
如果入队方法是这样 enqueue(Queue ** q,Tree * t)
那么传递给他的参数(Tree)那里必须 ...

[C] 纯文本查看 复制代码
void bfsTree(MGraph* g, Tree* t)


你这里函数不是定义t为指针了吗,你直接enQueue(&q,t) 是传给了它一个指针
而你这个函数void enQueue(Queue** q, Tree t)  第二参数只接受实参 ,
而 * 这个符号名字叫做取值符,你怕是忘了加了这个在t上意思为将t指针所指向的值取出。
也就是将取出的值给予了第二参数 ,并不是将指针给予了第二参数。这个问题太明显了!

你想要enQueue(&q,t)它接受t指针也就是必须void enQueue(Queue** q, Tree* t)这样。否自就必须加上取值符。
 楼主| ing 发表于 2020-1-29 18:40
我的爱是你 发表于 2020-1-29 17:50
你这里函数不是定义t为指针了 ...

可如果方法这样 void enQueue(Queue** q, Tree* t)
再这样调用 enQueue(&q,t)
就出现了第一张图片的运行结果,异常退出了。

然后,在 bfsForest 方法的最后一行代码是 bfsTree(g, t);
然而这个方法这样的声明

void bfsTree(MGraph * g,Tree * t)

却是可行的。
在定义函数 enQueue 这里却翻车了
我的爱是你 发表于 2020-1-29 19:18
19.jpg

改完函数确实可以接受指针,但你结构也应当做相应改变
3.jpg
否则node本来接受一个实参,现在你给它了一个指针并不匹配接受到的指针当然会出错。


2.jpg
同时第二个enQueue既然第二个参数接受指针 ,那么原来的temp也需要改动。
这里enQueue(&q, &temp);  可以直接将temp地址给予参数二  。
如都不进行改动 自然报错
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-26 20:50

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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