【问题标题】:want to figure out why struct elements changed while i didn't do anything想弄清楚为什么我什么都没做时结构元素发生了变化
【发布时间】:2019-09-16 09:49:24
【问题描述】:

它是一个 SqQueue,当我尝试获取队列中的元素时,我发现队列结构成员发生了变化,但我不知道为什么。当我第一次使用函数 myCircularQueueRear 时,obj 指向的结构元素发生了变化。在函数中,我没有更改这些数据。(leetcode 266)

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
#define MAXQSIZE 100
typedef int Status;
typedef int QElemType;
typedef struct{
    QElemType *base;
    int front;
    int rear;
    int size;
    int tag;
}MyCircularQueue,*SqQueue;

/** Initialize your data structure here. Set the size of the queue to be k. */

SqQueue myCircularQueueCreate(int k) {
    MyCircularQueue Queue;
    SqQueue Q=&Queue;
    Q->size=k;
    Q->tag=0;
    Q->base=(QElemType *)malloc(k*sizeof(QElemType));
    if(!Q->base)exit(OVERFLOW);
    Q->front=Q->rear=0;
    return Q;
}

/** Insert an element into the circular queue. Return true if the operation is successful. */
bool myCircularQueueEnQueue(SqQueue obj, int value) {
    if(obj->tag==1)return false;
    obj->base[obj->rear]=value;
    obj->rear=(obj->rear+1)%obj->size;
    if(obj->front==obj->rear)obj->tag=1;
    return true;
}

/** Delete an element from the circular queue. Return true if the operation is successful. */
bool myCircularQueueDeQueue(SqQueue obj) {
    if(obj->front==obj->rear&&obj->tag==0)return false;
    obj->front=(obj->front+1)%obj->size;
    if(obj->tag==1)obj->tag=0;
    return true;
}

/** Get the front item from the queue. */
int myCircularQueueFront(SqQueue Q) {
    if(Q->front==Q->rear&&Q->tag==0)return ERROR;
    return Q->base[Q->front];
}

/** Get the last item from the queue. */
int myCircularQueueRear(SqQueue Q) {
    if(Q->front==Q->rear&&Q->tag==0)return ERROR;
    return Q->base[(Q->rear+Q->size-1)%Q->size];
}

/** Checks whether the circular queue is empty or not. */
bool myCircularQueueIsEmpty(SqQueue Q) {
    if(Q->front==Q->rear&&Q->tag==0)return true;
    else return false;
}

/** Checks whether the circular queue is full or not. */
bool myCircularQueueIsFull(SqQueue Q) {
    if(Q->tag==1)return true;
    else return false;
}

void myCircularQueueFree(MyCircularQueue* Q) {
    free(Q->base);
}

int main(){
    SqQueue obj = myCircularQueueCreate(3);
    myCircularQueueEnQueue(obj, 1);
    myCircularQueueEnQueue(obj, 2);
    myCircularQueueEnQueue(obj, 3);
    myCircularQueueEnQueue(obj, 4);

当我运行以下行时,struct elemtents obj 指向的内容发生了变化。

    printf("%d ",myCircularQueueRear(obj));
    printf("%d ",myCircularQueueIsFull(obj));

    myCircularQueueDeQueue(obj);
    myCircularQueueEnQueue(obj, 4);
    printf("%d ",myCircularQueueRear(obj));
    /*int param_3 = myCircularQueueFront(obj);

    int param_4 = myCircularQueueRear(obj);

    bool param_5 = myCircularQueueIsEmpty(obj);

    bool param_6 = myCircularQueueIsFull(obj);

    myCircularQueueFree(obj);*/
    return 0;
}

IDE 推荐 stackoverflow

【问题讨论】:

  • 欢迎来到 Stack Overflow!听起来您可能需要学习如何使用debugger 来单步执行您的代码。使用好的调试器,您可以逐行执行您的程序,并查看它与您期望的偏差在哪里。如果您要进行任何编程,这是必不可少的工具。进一步阅读:How to debug small programs.
  • 你应该构造一个minimal reproducible example。有几个功能您甚至都不会使用,为什么要向我们展示它们呢?此外,您显然使用的是现代 C,其中包括 booltruefalse。那么为什么要使用#define FALSE 0 之类的呢?另外,你说有什么变化?你怎么知道的?你得到什么输出,你期望什么?

标签: c queue


【解决方案1】:

这里

SqQueue myCircularQueueCreate(int k) {
    MyCircularQueue Queue;
    SqQueue Q=&Queue;
    ...
    ...
    return Q;
}

你返回一个局部变量的地址。当函数返回时,该变量停止存在。所以之后使用指针访问系统中不再存在的对象。

使用动态分配而不是局部变量,即

SqQueue Q =malloc(sizeof *Q);

顺便说一句:typedef 的指针通常被认为是一个坏主意。

【讨论】:

    【解决方案2】:

    你在这里有一个 UB:

    SqQueue myCircularQueueCreate(int k) {
        MyCircularQueue Queue;  // stack allocation
        SqQueue Q=&Queue;
        Q->size=k;
        /* ... */
        return Q;  // returning the address of a stack object
    }
    

    完成该功能后,分配的结构将被释放

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-11-22
      • 1970-01-01
      • 2014-05-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-17
      相关资源
      最近更新 更多