【问题标题】:How to print a double pointer value in C如何在C中打印双指针值
【发布时间】:2018-06-07 09:51:35
【问题描述】:

我们正在为 C 中的通用类型数据实现一个优先级队列。我们认为指针等之间的分配是正确的,但我们不知道如何在最后打印“元素”的 int 值。你能帮助我吗?

#include <stdio.h>
#include <stdlib.h>

struct _pqElement{
  void** data;
  void** priority;
};

pqElement* pqElement_new(void* data, void* priority){
  pqElement* result = (pqElement*) malloc (sizeof(pqElement));
  result->data=&data;
  result->priority=&priority;
  return result;
}

static int* new_int(int value){
 int *elem=(int*)malloc(sizeof(int));
 *elem=value;
 return elem;
}

int main(int argc, char const *argv[]){
  pqElement * element = pqElement_new(new_int(1), new_int(85));
  printf("%d-%d", element->data, element->priority);
}

【问题讨论】:

  • “我们认为指针等之间的分配是正确的,”不,它们不是:result-&gt;data=&amp;data; 您分配了指针的本地副本的地址。离开该功能后,该地址无效。请改用result-&gt;data=data;priority 相同
  • 为什么要存储指向指针的指针?为什么要使用指针(甚至指向指针的指针)作为优先级?
  • 因为我们不知道要在队列中存储什么类型的数据。这就是为什么在结构中我们有一个 void** 指针来存储“new_int”给出的指针。但是我修复了result->data=data,但是你仍然知道如何打印出它所指向的整数值吗?
  • 改用void* 有什么问题?它可以指向任何数据类型。
  • 其实void*可以指向任何东西,但void**只能指向void*对象,所以void*更通用。

标签: c pointers priority-queue opaque-pointers


【解决方案1】:

你不需要两级指针。

#include <stdio.h>
#include <stdlib.h>

struct pqElement{
  void *data;
  void *priority;
};

struct pqElement* pqElement_new(void* data, void *priority)
{
  struct pqElement* result = malloc(sizeof(struct pqElement));
  result->data = data;
  result->priority = priority;
  return result;
}

static int* new_int(int value)
{
  int *elem = malloc(sizeof(int));
  *elem=value;
  return elem;
}

int main(int argc, char const *argv[])
{
  struct pqElement *element = pqElement_new(new_int(1), new_int(85));
  printf("%d-%d", *(int*)element->data, *(int*)element->priority);
}

最后打印值需要以正确的方式转换指针,正如 Alexander Pane 已经提到的那样。

使用不同类型的优先级也会使队列不那么通用。需要为排序、打印等提供不同的功能。

【讨论】:

  • 我们将“priority”设置为“void*”,因为我们还需要使用相同的代码来实现Prim的算法,其权重为float值。
【解决方案2】:

代码甚至无法编译,因为从未定义过 pqElement 类型,而只定义了 _pqElement 结构体。

同样你在printf中使用了%d,但是你传递的参数是void**,所以你需要转换值。

这些改变应该可以解决问题:

#include <stdio.h>
#include <stdlib.h>

typedef struct _pqElement{
    void** data;
    void** priority;
} pqElement;

pqElement* pqElement_new(void* data, void* priority){
    static pqElement* result;
    result = (pqElement*) malloc (sizeof(pqElement));
    result->data=&data;
    result->priority=&priority;
    return result;
}

int* new_int(int value){
    static int *elem;
    elem = (int*)malloc(sizeof(int));
    *elem=value;
    return elem;
}

int main(int argc, char const *argv[]){
    pqElement *element = pqElement_new(new_int(1), new_int(85));
    printf("%d-%d\n", **((int**)(element->data)), **((int**)(element->priority)));
    //need to free the memory allocated with the malloc, otherwise there is a possibility of memory leakage!
}

这只会打印第一个元素,但您可以使用偏移量来指向后面的元素。

注意:正如我在代码中的注释所报告的,您需要释放使用 malloc 分配的内存,否则您有潜在的内存泄漏!

【讨论】:

  • 在您的代码中也存在在pqElement_new 中使用非静态地址且返回后无效的问题。
  • 添加的static关键字是为了解决问题吗?
  • 对不起,我实际上错误地使用了静态关键字。我更新了答案。添加 static 关键字可确保变量存储在内存的静态部分而不是堆栈中。先前的答案有效,但存在安全问题,因为函数的堆栈变量在函数终止时被取消引用并且指针可能被覆盖。您可以在此处找到有关内存划分的一些详细信息:stackoverflow.com/questions/408670/…
  • datapriority 的使用是问题所在,而不是 element
【解决方案3】:

谢谢各位。 我需要代码也适用于字符串,所以我这样做了:

static char* new_string(char* value){
  char* elem= malloc (sizeof(char));
  strcpy(elem, value);
  return elem
}

像这样打印出来:

 int main(int argc, char const *argv[]){
   struct pqElement *element = pqElement_new(new_string("Hello"), 85);
   printf("%s-%d", *(char*)element->data, element->priority);
 }

【讨论】:

  • 你需要分配strlen(value)+1字节。不仅 1. 对于打印,您需要删除前导 *
  • 顺便说一句:这不是答案,您不应将其作为答案发布。而是添加一个新问题或扩展您的问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-01-29
  • 2023-03-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多