1

简而言之,我有一个模板类 Tree ,它有一个createTree(Data* arrayData[])方法。此方法接收指向 Data 类型数据的指针数组:

template<class Data>
void Tree<Data>::createTree(Data* arrayData[]) {
    m_indexCreation = 0;
    cout << sizeof(arrayData) / sizeof(int) << endl;
    m_root = createChildTree(arrayData);
}

在我的main()函数中,我创建了一个指向字符串对象的指针数组并填充它。然后我尝试将它传递给createTree()方法,但在方法内部,数组的大小变为 1。换句话说,方法内部的计数打印“1”。这是我的main()

int main() {
    string* tab[20];

    for ( int i = 0 ; i < 20 ; i++ ) {
        if ( i % 3 != 0 ) {
            tab[i] = new string("James Johnson");
        } else {
            tab[i] = NULL;
        }
    }

    Tree<string> tree;
    tree.createTree(tab);

    tree.display(tree.getRoot());
}

我可以毫无问题地在 中打印整个数组的值main(),但是在 中createTree(),数组以某种方式减小到 1 的大小,单个值为 NULL。

我究竟做错了什么?

4

2 回答 2

1

检查 C 常见问题

http://c-faq.com/aryptr/aryparmsize.html

答:编译器假装数组参数被声明为一个指针(即在示例中为 char *a;参见问题 6.4),并且 sizeof 报告指针的大小。另见问题 1.24 和 7.28。

解决方法。将大小作为参数传递。

void Tree<Data>::createTree(Data* arrayData[], int sz)
{
    ...
}

Tree<string> tree;
tree.createTree(tab, sizeof(tab)/sizeof(tab[0]));
于 2013-04-07T00:48:11.553 回答
1

tab被发送到函数中时,它将进行数组到指针的转换:

来自 C++ 标准,4.2 [标准转换]

“NT 数组”或“T 的未知边界数组”类型的左值或右值可以转换为“指向 T 的指针”类型的纯右值。结果是指向数组第一个元素的指针。

因此,您的初始签名将类似于以下内容:

Tree<Data>::createTree(Data** arrayData);

如您所见arrayData,因为是双指针。使用sizeof时,它将返回指针的字节数,而不是实际数组的字节数。要解决此问题,您应该通过引用传递数组:

template <class Data, unsigned N>
createTree(Data* (&arrayData)[N]); // you can print out N for the size
//                                    but sizeof(x)/sizeof(*x) will still work

或者您可以使用std::vector,因为它更容易获得大小:

#include <vector>

void Tree<Data>::createTree(std::vector<Data*> arrayData)
{
    std::cout << arrayData.size();
}

int main()
{
    std::vector<std::string> tab;

    for (int i = 0; i < 20; ++i) // shortened for this example
    {
        tab[i] = new std::string("James Johnson");
    }

    ...
}

我认为这是一个更清洁的选择。我希望这会有所帮助。

于 2013-04-07T00:50:59.423 回答