【问题标题】:Reading to char * always has same address读取 char * 始终具有相同的地址
【发布时间】:2018-06-26 05:42:41
【问题描述】:

我有一个这样的结构:

struct Node {
    void *data;
    Node *l, *r;
}

我应该使用函数:

void push(Queue *q, void *data, int priority) {
    Node *n = new Node;
    n->data = data;

   // place node in queue
}

我试图在循环中读取字符串,但之后我得到了节点中所有值都相似的队列。

void read_input(Queue *q) {
    string s;
    int p;
    cin >> s >> p;

    // problem is here
    push(q, (void *) s.c_str(), p);
}

void main() {
    Queue *q = create();

    for (int i = 0; i < 5; i++) {
        read_input(q);
    }
}

我该如何解决这个问题?为什么string s 总是有相同的地址?

【问题讨论】:

  • 这不是c,那你为什么要这样标记它?
  • 什么是create()
  • 你能贴出推送的代码吗,我想你是在为数据分配地址,而不是在其中分配和复制字符串
  • 什么是Queue?发布minimal reproducible example
  • @MaximSamburskiy 您正在使用 C++,因此您不必费心编写自己的容器,但您应该使用 std 容器,在您的情况下可能是 std::queue

标签: c++ queue void void-pointers


【解决方案1】:

就像 Trantor 所说,您使用的是 s.c_str() ,它是字符串 s 的私有指针;并且仅在 read_input 函数内有效。

每次调用 read_input 都会使用这个指针,每次到达 read_input 结束时都会销毁(超出范围)。

您看到相同的指针,可能是因为它在堆栈上。巧合。

要解决您的问题,您需要创建字符的副本并将它们存储在 node->data 中。但是,您还需要考虑在哪里删除它。例如。 OnNodeDestroy 事件或类似事件。

【讨论】:

    【解决方案2】:

    问题是,您在队列推送调用中保存了指向 std::string 类临时对象的私有内部的(临时)指针。离开read_input后就失效了,甚至可能在内部被重用,所以指针好像没有变化。

    您应该使用副本,为字符串分配您自己的内存。

    【讨论】:

      【解决方案3】:

      当您创建一个字符串对象时,编译器将从堆栈中分配内存,并且该字符串对象将始终指向该特定内存位置(在这种情况下为静态内存分配)。在您的结构中 void *data 指针也将始终指向相同的内存位置。因此,输入字符串对象的最后一个值将反映在堆栈中的所有节点中。要解决这个问题,您必须每次动态分配内存,以便数据指针指向不同的内存位置,您将获得不同的值。

      void read_input(Queue *q) {
          //string s;
          char *s = (char *)malloc(50);
          int p;
          cin >> s >> p;
          push(q, (void *) s, p);
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-05-13
        • 1970-01-01
        • 2018-08-07
        • 1970-01-01
        • 1970-01-01
        • 2013-09-29
        相关资源
        最近更新 更多