1

Briefly, I have a template class Tree which has a createTree(Data* arrayData[]) method. This method receives an array of pointers to data of type Data :

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

In my main() function, I create an array of pointers to string objects and fill it. I then try to pass it to the createTree() method, but inside the method the array becomes of size 1. In other words, the count inside the method prints "1". Here's my 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());
}

I can print without problem the values of the whole array in the main(), but in createTree(), the array somehow reduces to a size of 1, with single value of NULL.

What am I doing wrong?

5
  • sizeof(tabDonnees) / sizeof(int) probably produces 1. You're dividing the size of a pointer by the size of an int. Also, the method creerArbre (createTree) cannot determine the size of tab, it is only passed in by address, and it does not store its size, nor does the compiler pass its size. Commented Apr 7, 2013 at 0:45
  • @Alexis Leclerc, hi Alexis, welcome to SO. Please take into account that most of users of SO are worldwide developer. It's is a bad idea to post code that is either in french, spanish, indian, or deutsch, or arabic or anything. I translated it. Commented Apr 7, 2013 at 0:48
  • @StephaneRolland - does it matter? His Question itself was in English. Only classnames, function names were in a different language. And didn't matter. Commented Apr 7, 2013 at 1:10
  • @user93353 well it does'nt matter for me I am French, and his code was in French ;-) But I remember when I saw Hindi, Indonesian, variable names and functions... It really didn't help me understand what was going on in the code... We are in a international site of inter-aid. If you ask Meta I think I read one Q/A that stated the English was the language of this site. That's what I remember. Maybe there were answers stating the contrary was acceptable inside the code, but I don't remember them. ;-). Commented Apr 7, 2013 at 1:15
  • Thanks for the notice, I'll translate my code next time ;) and thanks for translating ! Commented Apr 7, 2013 at 1:27

2 Answers 2

1

Check the C FAQ

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

A: The compiler pretends that the array parameter was declared as a pointer (that is, in the example, as char *a; see question 6.4), and sizeof reports the size of the pointer. See also questions 1.24 and 7.28.

The workaround. Pass the size as a parameter.

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

Tree<string> tree;
tree.createTree(tab, sizeof(tab)/sizeof(tab[0]));
Sign up to request clarification or add additional context in comments.

Comments

1

When tab is sent into the function it will undergo array-to-pointer conversion:

From the C++ Standard, 4.2 [Standard Conversions]

An lvalue or rvalue of type “array of N T” or “array of unknown bound of T” can be converted to a prvalue of type “pointer to T”. The result is a pointer to the first element of the array.

Thus, your initial signature will look similar to this:

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

As you can see arrayData because a double-pointer. When you use sizeof, it will return the number of bytes for the pointer but not for the actual array. To fix this, you should pass the array through a reference:

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

Or you can use std::vector as it is much easier to obtain the size:

#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");
    }

    ...
}

This in my opinion is a cleaner alternative. I hope this helped.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.