【问题标题】:Pointer to pointer confusion指针混淆
【发布时间】:2009-07-06 08:39:26
【问题描述】:

编辑:队列是 2d 的原因是因为我需要一个 Command 指针,以便 cmd 可以等于 NULL。空==(无效*)。这就是我感到困惑的地方,也是我来这里的原因。 :)

为了帮助尝试找出我在 Python 中遇到的另一个问题,我正在用 C 语言实现一个小型测试程序。虽然我知道一点,但显然我很困惑。我正在尝试编写一个用于异步 USB 传输的简单队列。队列有问题,因为从队列中弹出的每个命令都是相同的。如果我将 queue[1024][0] 写为 queue[1024][1],则该命令会在两个不同的命令之间交替,并且程序在 command_thread_main 中崩溃。显然它没有注意到 cmd 应该为 NULL。据我所知,将 [1] 更改得更高没有任何效果。有什么提示吗?

typedef struct Command {
    void (*cb) (char *data, int size);
    unsigned char *data;
    int size;
} Command;

struct Command queue[1024][0];

int queueEnd = 0;
int queueStart = 0;

static void queue_push(void (*cb), unsigned char *data, int size) {
    if (queueEnd >= 1024)
        return;
    queue[queueEnd]->cb = cb;
    queue[queueEnd]->data = data;
    queue[queueEnd]->size = size;
    queueEnd++;
}

struct Command * queue_pop(void) {
    if( queueStart > queueEnd )
        return NULL;
    return queue[queueStart++];
}

static void *command_thread_main(void *arg) {
    struct Command *cmd;
    while (!do_exit) {
        if(locked) continue;
        locked = 1;
        cmd = queue_pop();
        if(cmd != NULL)
            cmd->cb(cmd->data, cmd->size);
    }
}

【问题讨论】:

  • 为什么数组是二维的?看起来不对

标签: c pointers


【解决方案1】:

我认为您有一个错误需要先修复。您有一个二维命令数组,并将其中一个维度设置为零!

struct Command queue[1024][0];

当您访问队列时,您似乎将其视为一维结构。您是否应该将其声明为:

struct Command queue[1024];

【讨论】:

  • 要么让 queue_pop 返回 &queue[queueStart++] 要么将数组更改为 Command *
【解决方案2】:
  • 你不是说struct Command queue[1024];吗? (也就是说,没有 [0][1] 或其他。)
  • queue_pop 我认为你应该测试queueStart >= queueEnd
  • 你应该实现一个循环数组。

现在您将结构本身存储在一个数组中,而不是指向它的指针。这是明智的。不过,您需要将 -> 更改为 .

queue[queueEnd].cb = cb;
queue[queueEnd].data = data;
queue[queueEnd].size = size;

(因此queue_pop 应该返回一个struct Command 类型的变量(而不是struct Command *),并且主代码也应该相应地更新。)

当然,您也可以传递指针,但是对于这么小的结构/队列,实际上并没有必要。

【讨论】:

  • 1) 我需要一个指针。 2) 一旦 queueStart 超过 queueEnd,队列就被认为是空的。当 queueStart == queueEnd 时,队列至少有一个成员要弹出。 3) 这个队列将被使用一次,最多有 65 个命令通过它。这是一个简单的测试程序,可以满足帮助我在 Python 中调试问题的人的需求。不需要循环数组!
  • 最初是queueStart = queueEnd = 0,所以queueStart > queueEnd是假的,而队列实际上是空的。你的代码永远不会弹出最后一个命令。
  • 更有意义。 :)
  • 对不起,我说错了:您的代码将一个值弹出到多个值(这将导致未定义的行为)。
【解决方案3】:

正如其他人所指出的,2D 队列绝对是错误的。你需要一个一维队列,我怀疑你想要的是一个指针数组:

Command * queue[1024];

我建议你去思考一下这个问题,画一些图表,然后带着更清晰的代码和问题回来。

【讨论】:

    【解决方案4】:

    另一个问题是您已将队列声明为structs 的数组,但您通过使用取消引用-> 运算符而不是成员资格. 将其用作指向结构的指针数组.

    我的意思不是听起来刻薄,但编译器警告标志(-Wall 用于 gcc)是你的朋友。

    【讨论】:

    • 1) 这就是我在这里的原因。很明显我做错了什么,但我不确定那可能是什么。你会如何建议我这样做? 2)啊,是的,我是 C 和编译 C 的新手。感谢编译器提示。
    • 因为它是一个简单的程序,队列是一个全局变量,队列中没有空间被重复使用我只是让 pop 返回一个弹出值的索引,或者如果队列返回 -1是空的。另外,你应该使用正确的互斥锁,真的。
    • 嗯,绝对不需要互斥锁。在线程启动之前,队列已满。就像我说的,这是一个非常简单的程序。我只需要一个队列来保存大约 65 个 USB 传输供 command_thread_main 使用。
    • 我的错;我对在您的示例中使用“锁定”变量感到困惑。
    • 啊,是的 :) 该状态会随着每次 USB 传输 (true) 和相应的回调 (false) 而变化。
    猜你喜欢
    • 2010-09-25
    • 2011-09-04
    • 2016-11-08
    • 2012-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多