【问题标题】:Error reading vector elements via a pointer which has the base address of the vector通过具有向量基地址的指针读取向量元素时出错
【发布时间】:2018-08-23 21:35:10
【问题描述】:

我的 exe 正在访问 dll 分配的向量。我通过vector.data()获取基地址。问题是向量分配的内存空间可能比需要的多。那么如何读取分配了实际数据的内存。

.dll 代码

Utf8String ICSClient::SampleMethod2(Utf8String* &p) 
    {
    vector<Utf8String> *temp = new vector<Utf8String>;
    temp->push_back("Liu");
    temp->push_back("Roy");
    temp->push_back("Shanu");

    p = temp->data(); // returns the pointer to the underlying array

    return success;
    }

.exe 代码 // -----p 是一个指针,分配了向量的基地址

while (p != NULL)
     {
      cout << *p << endl;
      p++;
     }

看来p不等于null,然后在读取非null的内存时抛出异常。

【问题讨论】:

  • 为什么不返回向量?修改传入的参数以指向在堆上分配的东西看起来像是一种正确的代码气味。
  • 至少您还需要返回向量的size,但正如@super 所写,最好的办法就是返回对vector 的引用。
  • 我没有返回引用,因为我不确定在本机代码中使用 dll 时是否支持 STL。
  • 我认为@Rotem 提出了最好的建议(添加一个参数来返回向量的大小),但如果由于某种原因不可行(?),你可以使用一个哨兵值比如空字符串作为向量的结尾?
  • 您还应该担心 分配和解除分配 发生的机制从 dll 到 exe 匹配,但您似乎忽略了泄漏。避免在 dll 和 exe 之间进行任何所有权传输会更安全。

标签: c++ pointers stl


【解决方案1】:

p 本身不会等于NULL。无法准确判断,因为提供的代码缺少p 指针定义和ICSClient::SampleMethod2 调用,但在这里您正在读取数组,然后您超出了数组的范围,即Undefined Behaviour

还有内存泄漏,因为您从未释放分配给 vector 的内存,并且在函数结束时丢失了指向它的指针。

我看到你在这里返回了一些代码,这可能是一个要求,所以你不能返回向量。我建议通过引用传递std::vector,这样你就可以在你的函数中使用它

Utf8String ICSClient::SampleMethod2(std::vector<Utf8String>& data) 
{
    data.clear();
    data.push_back("Liu");
    data.push_back("Roy");
    data.push_back("Shanu");

    return success;
}

编辑:如果通过引用传递std::vector 是不可行的选择,那么您(和您的 dll 的用户)将不得不处理原始 C 数组。不幸的是,当将数组传递给函数时,它会降级为指针类型,因此必须将大小与数组一起传递

Utf8String ICSClient::SampleMethod2(Utf8String** data, size_t* size) 
{
    *size = 3;

    *data = new Utf8String[3];
    data[0] = "Liu";
    data[1] = "Roy";
    data[2] = "Shanu";

    return success;
}

请注意,用户必须自己管理内存(删除数组),这并不是真正的预期行为。

【讨论】:

  • 我可能无法将 std::vector 作为参考传递,因为我的 dll 可能被本机代码使用,我不确定本机代码是否支持 STL。跨度>
  • 我正在 Microsoft Visual Studio 上构建 dll
  • 我编辑了答案,但您似乎已经找到了答案:)
  • 由于我的代码可能与本机应用程序一起使用,我担心向量的可用性。由于我创建的应用程序位于.net 中。我找到的解决方案是让用户传递一个指针引用,这样当 dll 被使用时,dll 将初始化 dll 用户传递的指针引用,然后用户将不得不处理内存管理。由于 dll 也适用于本机应用程序,因此不可能有其他解决方案。 :) 抱歉回复晚了@Yksisarvinen
猜你喜欢
  • 1970-01-01
  • 2021-10-14
  • 2011-03-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-16
相关资源
最近更新 更多