【问题标题】:C -- (void*) to intC -- (void*) to int
【发布时间】:2011-06-28 01:07:27
【问题描述】:

我正在用 C 语言为内核实现一个简单的优先级队列,因此我不能使用任何标准库。队列中有一个头节点,每个节点都指向队列中的下一个节点。

typedef struct node node;
struct node {
    node *next;
    void *data;
};

typedef struct  {
    node *head;
    int n;
} queue;

如您所见,每个节点都将数据保存在 void* 中。当我将数据从堆栈中弹出时,我无法将此数据转换为 int。

//push data
int int_data = 100;
push(q, &int_data);
//...
//pop data
node* popped = pop(q);
int *pop_data = popped->data;
printf("pop data (100): %d\n", *pop_data);

为什么我不能在这里得到原始值?我似乎正在打印一个指针值。或者,有没有更好的方法来处理这个问题?

== 编辑(抱歉应该包含这些):

void push(queue *q, void *data)
{
    node new;
    new.data = data;
    node *new_ptr = &new;

    if(is_empty(q))
    {
        q->head = new_ptr;
        q->n++;
        return;
    }

    int i;
    node *curr = q->head;
    for(i=0; i<q->n; i++)
    {
        curr = curr->next;
    }
    curr->next = new_ptr;
    q->n++;
}

node* pop(queue *q)
{
    node *curr = q->head;
    q->head = curr->next;
    return curr;
}

【问题讨论】:

  • 根据您提供的信息,我认为我们没有足够的信息来回答您的问题;只要您正确设置了所有内容,这应该可以正常工作。程序实际打印的是什么?您能否提供更多有关这些功能如何工作的背景信息?
  • 只要说printf("...", popped-&gt;data);就行了
  • 您正在存储一个局部变量的地址,一旦它从堆栈中弹出,您的void* data 将指向垃圾内存。

标签: c pointers queue


【解决方案1】:

您的代码是否都在一个函数中?如果不是,int int_data 将从堆栈中弹出(不是您的队列,实际堆栈),这可能是您打印垃圾的原因;您正在存储局部变量的地址。

我建议将void* data 更改为int data。 (如果需要,可以将地址存储在 int 中,稍后可以将其转换回指针。)

int int_data = 100;
push(q, int_data);

node* n = pop(q);
int num = n->data;

再次查看您的代码后,您在添加新节点时遇到了同样的问题。 node new 在函数结束时超出范围,所以基本上你队列中的所有节点都指向无效内存。

【讨论】:

  • 这似乎是最相似的原因。将 void* 转换为 int* 肯定适用于任何其他场景
  • 不要在int中存储地址;如果您需要存储地址或int,请使用union
【解决方案2】:

如果“pop”操作在不同的函数中:

问题可能是因为您将局部变量推入队列。

当你去弹出时,这个地址不再有效(或者至少不指向一个 int 值),所以你打印了一些奇怪的东西。由于数据不再指向您的 int,它可能看起来像一个内存地址。

【讨论】:

    【解决方案3】:

    您可以使用 glib GPOINTER_TO_INT 宏:

    #define GPOINTER_TO_INT(p) ((gint)  (glong) (p))
    

    但是,请注意文档注释:

    您不得将指针存储在 整数。这不是便携式的 方式形状或形式。仅这些宏 允许在指针中存储整数, 并且只保留 32 位 整数; a 范围之外的值 32 位整数将被破坏。

    【讨论】:

      【解决方案4】:

      您是在设置 data = int_data (i.e. int --> void*) 还是 data = &amp;int_data (i.e. int* --> void *) ?在前一种情况下,你必须写printf("pop data (100): %d\n", pop_data);

      【讨论】:

        猜你喜欢
        • 2016-01-05
        • 1970-01-01
        • 2018-03-16
        • 2014-01-28
        • 1970-01-01
        • 2023-03-30
        • 2018-05-05
        • 1970-01-01
        • 2012-04-04
        相关资源
        最近更新 更多