4

I need to use an array of strings with an unknown size. Here I have an example to see if all works fine. I need to know that array's size in ClassC but without passing that value as an argument. I've see so many ways to do it (here and in google) but as you will see now, they didn't work. They return the number of chars in the first position of the array.

void ClassB::SetValue()
{
    std::string *str;
    str = new std::string[2]; // I set 2 to do this example, lately it will be a value from another place
    str[0] ="hello" ;
    str[1] = "how are you";
            var->setStr(str);
}

Now, in ClassC if I debug, strdesc[0] ="hello" and strdesc[1] = "how are you", so I suppose that class C is getting the info ok....

void classC::setStr(const std::string strdesc[])
{
    int a = strdesc->size(); // Returns 5
    int c = sizeof(strdesc)/sizeof(strdesc[0]); // Returns 1 because each sizeof returns 5
    int b=strdesc[0].size(); // returns 5

    std::wstring *descriptions = new std::wstring[?];
}

So.. in classC, how can I know strdesc's array size, that should return 2?? I have also tried with:

int i = 0;
while(!strdesc[i].empty()) ++i;

but after i=2 the program crashes with a segmentation fault.

Thanks,

Edit with the possibles SOLUTIONS:

Conclusion: There is no way to know the array's size once I pass its pointer to another function

  1. Pass the size to that function... or...
  2. Use vectors with std::vector class.
Megasa3
  • 766
  • 10
  • 25
  • 4
    use a `std::vector`. – 463035818_is_not_an_ai Sep 02 '15 at 09:45
  • There's no (standard) way of getting the size of you just have a pointer to, you need to keep track of it yourself. And doing `sizeof` on a pointer will give you the size of the pointer (usually 4 on 32-bit systems and 8 on 64-bit systems). – Some programmer dude Sep 02 '15 at 09:46
  • You cannot unless you pass it as a type where the size is known (fx `std::vector` or `const std::string strdesc[2]`). – skyking Sep 02 '15 at 09:47
  • 1
    btw... "so many ways to do it (here and in google) but as you will see now" ... I do not know any, and I also do not see any that would work for a array of strings in your code... just do not use c-style arrays when you are writing c++ – 463035818_is_not_an_ai Sep 02 '15 at 09:48
  • @skyking as i said 2 is an example. the parameters will be given by a server so maybe today is 2, maybe later is 5.. – Megasa3 Sep 02 '15 at 09:50
  • @tobi303 just an example: http://stackoverflow.com/questions/4108313/how-do-i-find-the-length-of-an-array – Megasa3 Sep 02 '15 at 09:50
  • @Megasa3 the top answer cannot work for an array of strings because the strings have different lengths. – 463035818_is_not_an_ai Sep 02 '15 at 09:52
  • @Megasa3 you can get the size of an array just fine. But not by using just a pointer, which is what you have as the argument of `setStr`. None of the answers in that question attempt to do that. – eerorika Sep 02 '15 at 09:52
  • @Megasa3 the second answer might work, but this is just a workaround for c-style arrays that you do not need if you use c++ vectors – 463035818_is_not_an_ai Sep 02 '15 at 09:53
  • 1
    On an unrelated note, `sizeof(strdesc[0])` will **NOT** return `strdesc[0].size()`. No realistic compiler will have `sizeof(std::string)` be equal to 5 either. Typically you have _at least_ 8 bytes (twice the size of a pointer, begin and end or begin and length). – MSalters Sep 02 '15 at 09:53
  • @user2079303 then, you mean that I should pass the array in classC in another way or should I just use a vector? – Megasa3 Sep 02 '15 at 09:56
  • @Megasa3 Then you cannot use that type (`const std::string[2]`) and have to use another type where the length is known (fx `string::vector`). The type you used in the example simply doesn't contain information on the size of the array. – skyking Sep 02 '15 at 09:56
  • @Megasa3 vector is what I recommend in my answer. – eerorika Sep 02 '15 at 10:03
  • @user2079303 ok, thank you so much everybody!! – Megasa3 Sep 02 '15 at 10:09

2 Answers2

1

With this Kind of code you will get memory leaks and other kind of C-style problems.

use vector:

    #include <vector>
    #include <string>
    #include <iostream>
    ...
    std::vector<std::string> my_strings;
    my_strings.push_back("Hello");
    my_strings.push_back("World");

    std::cout << "I got "<< my_strings.size() << " strings." << std::endl;

    for (auto& c : my_strings)
            std::cout << c << std::endl;
schorsch_76
  • 794
  • 5
  • 19
  • that was my first idea, and in fact I did it with vectors but thought that an array would be better... so I'll have to pass a `std::vector *myvector` as a parameter in classc? – Megasa3 Sep 02 '15 at 09:52
  • 1
    No, just pass a reference or pass by value. C++11 has move semantics. (no deep copy). C-Style Arrays are not very nice to manage. If you want an Array, use std::array. – schorsch_76 Sep 02 '15 at 09:58
  • i'll take a look at it too, didn't know there were a std::array with a fixed size. Thanks – Megasa3 Sep 02 '15 at 10:01
1

how can I know strdesc's array size

You cannot know the size of an array from a pointer to that array.

What you can do is pass the size as another parameter. Or even better, use a vector instead.

but after i=2 the program crashes with a segmentation fault.

Accessing beyond the array boundary has undefined behaviour.

eerorika
  • 232,697
  • 12
  • 197
  • 326
  • `Accessing beyond the array boundary has undefined behaviour.` that was what i supposed but found it as a solution here too so I tried... then i understand that i just can pass the size too or use a vector, right? – Megasa3 Sep 02 '15 at 09:57
  • 1
    Well if you want to be silly, you could demand that the user of `classC::setStr` must always pass an array which always ends in empty string. In that case your while loop would work. For example: user wants to pass "hello" and "world". So he would create an array with strings {"hello","world",""}. Your loop would then figure out that there are 2 valid strings in the array because the third is empty. Of course, that would fail miserably if the user of the function attempts to pass an array without empty strings or if empty strings should be considered as valid input. I recommend vector instead. – eerorika Sep 02 '15 at 10:09