在C ++中从函数返回2D数组

3

我有一个这样声明的函数:

unsigned char** Classifier::classify(){
      //...
    unsigned char **chars = new unsigned char *[H];
for(int i = 0; i < H; i++)
    chars[i] = new unsigned char[W*3];

//...

return &chars;
//note: when this is "return chars;" I get the following:  cannot convert ‘unsigned char*’ to ‘unsigned char**’ in return

这给我一个警告:

Classifier.cpp: In member function ‘unsigned char** Classifier::classify()’:
Classifier.cpp:124: warning: address of local variable ‘chars’ returned

这样忽略是否可以?基本上,我的问题是如何返回在函数中定义的数组的引用?
我希望能够做到:
unsigned char** someData = classify();

2
如果不必要,请勿使用原始数组。请改用std::vector。 - Juraj Blaho
6个回答

6

只返回数组,而不是它的地址:

return chars;

&chars 是一个指向指针的指针,但 chars 是一个指向指针的指针(这是你想要的)。请注意,chars 不是一个数组。指针和数组不是同一种东西,尽管它们经常被混淆。


我一开始尝试了这个,但是当我去掉addressof时,我得到了这个错误:无法将“unsigned char*”转换为“unsigned char**”作为返回值。 - Derek
@Derek:试试这个:给我展示一下代码,确切地写成 return chars; 并且会出现那个错误信息。 - Adam Rosenfield

3

忽略这个是永远不可取的。你返回了一个局部变量的地址。当你离开classify()的堆栈帧时,该地址将变为无效,在调用者有机会使用它之前。

您只需要返回该变量的值即可:

return chars;

如果我去掉 &,那么返回值会变成“无法将 'unsigned char*' 转换为 'unsigned char**'”。 - Derek
1
这意味着您将chars声明为unsigned char *,而不是像上面代码中的unsigned char ** - Frédéric Hamidi
啊,你说得对 - 我忘记在编译器中包含一些标志来编译不同的代码部分了!谢谢! - Derek

3

@Adam Rosenfield已经给出了正确答案,还有其他一些人也是,但是作为思考的食粮,一个不错的方法是使用std :: vector(of std :: vectors)并将其作为引用参数传递到函数中。

#include <vector>

void Classifier::classify(std::vector<std::vector<unsigned char>> & chars)
{
      //construct a vector of W*3 integers with value 0
      //NB ( this gets destroyed when it goes out of scope )
      std::vector<unsigned char> v(W*3,0);

      //push a copy of this vector to the one you passed in - H times.
      for(int i = 0; i < H; i++)
         chars.push_back(v);
}

chars被填充了你想要的内容,当涉及到删除vector时,你不必担心如何调用正确的delete[]语法,这与在2D数组中调用两个new函数不同。

你仍然可以像对待2D数组一样引用此向量中的项,例如:chars[5][2]或其他。

尽管我能理解你想要做到:

 unsigned char** someData = classify();

所以如果你想使用向量,你需要将someData声明如下:
 std::vector<std::vector<unsigned char>> someData;

为了使这更加清晰明了:

typedef std::vector<std::vector<unsigned char>> vector2D;
vector2D someData;
classify(someData);
...

1
  1. 如果在函数中定义了一个数组,并且你想在函数外部使用它,你应该将其(数组)声明为静态的或在函数外部声明一个数组并将其作为参数传递。

  2. 仅使用 "return chars;"


0
不,忽略那个警告是不可以的。你返回的值是栈上chars的地址,而不是它所指向的内容。你应该只返回chars

0

其他人已经给出了答案;但是作为一般性的观察,我建议您看看STL。您已经标记了C和C++问题,因此我假设您在C++环境中,并且STL可用。您可以使用typedef来以可读的形式定义向量,甚至是向量的向量(即2D数组)。然后,您可以返回指向您的向量的指针或引用(视情况而定)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接