luaT_pushudata 返回适当的 Tensor 类型和维度,但却是垃圾数据

我有一个 C++ 代码片段,理论上应该能够创建和返回一个 torch.IntTensor 对象,但是当我从 Torch 中调用它时,我得到的是垃圾数据。

以下是我的代码(请注意,此代码片段略去了函数注册部分,但是可以保证注册成功--如果需要我可以提供它):

static int ltest(lua_State* L)
{
    std::vector<int> matches;
    for (int i = 0; i < 10; i++)
    {
        matches.push_back(i);
    }

         performMatching(dist, matches, ratio_threshold);
         THIntStorage* storage = THIntStorage_newWithData(&matches[0], matches.size());
         THIntTensor* tensorMatches = THIntTensor_newWithStorage1d(storage, 0, matches.size(), 1);

    // 把结果推到 Lua 栈
    luaT_pushudata(L, (void*)tensorMatches, "torch.IntTensor");
    return 1;
}

我从 Lua 调用它时,应该得到一个大小为 10 的 [torch.IntTensor],而我确实得到了。但是,数据似乎是内存地址或垃圾数据:

 29677072
        0
 16712197
        3
        0
        0
 29677328
        0
  4387616
        0
[torch.IntTensor of size 10]

它本应该是 [0,9] 的数字。

我错在哪里了?


值得一提的是,当我在 C++ 中进行测试时,

for (int i = 0; i < storage->size; i++)
    std::cout << *(storage->data+i) << std::endl;

打印出正确的值。

同样地,

for (int i = 0; i < tensorMatches->storage->size; i++)
    std::cout << *(tensorMatches->storage->data+i) << std::endl;

也是一样的,所以我认为问题在于 C++ 和 Lua 之间的交互。

点赞
用户3427580
用户3427580

我在别的地方得到了一个答案 - Torch7 的 Google 群组 - 但我将在此复制并粘贴它,以便任何需要的人都可以使用。

来自用户 @alban desmaison:

你的问题实际上是内存管理。

当你的 C ++ 函数返回时,你的 vector<int> 是自由的,它的内容也是自由的。 从那时起,张量指向的是自由内存,当你访问它时,你访问的是已释放的内存。 你要么:

  • 使用 malloc 在堆上分配内存(作为 int 数组),并像你目前所做的那样使用 THIntStorage_newWithData(当它不再被 Torch 使用时,你给 newWithData 的指针将被 free 掉)。
  • 像你现在一样使用一个 vector<int>,但使用 THIntTensor_newWithSize1d(matches.size())创建一个具有给定大小的新张量,然后将向量的内容复制到张量中。

值得一提的是,我无法使用 malloc 使它正常工作,但是复制内存的方法就可以正常工作了。

2016-09-02 16:29:49