0

Hi I am just starting to learn cpp and I have two examples of getting the size of a vector in the for statements both seem to work but which is right and why? sizeof(vector) or vector.size()?

Thanks

Brian

void print_vector(vector<string> vector_to_print){
    cout << "\nCars vector = ";
    for(int i = 0; i < sizeof(vector_to_print); i++){
        cout << vector_to_print[i];
        (i < vector_to_print.size()-1) ? (cout << ", ") : (cout << endl); // ? the tenrary operator is an if statement (?) do one outcome (:) or the other
    }
}

void print_vector(vector <string> vector_to_print){
    cout << "\nVector contents = ";
    for( int i = 0; i < (vector_to_print.size()); i++ ){
        cout << vector_to_print[i];
        (i < (vector_to_print.size()-1)) ? (cout << ", ") : (cout << endl);
    }
}

Both seem to work I try to rewrite the same code from memory each day for a week to help me learn it and I couldn't quite get the sizeof() to work so I googled it and the example I found used .size() but when I got home and checked what I did yesterday I had used sizeof().

BrianDawe
  • 23
  • 6
  • 1
    The latter is correct – πάντα ῥεῖ Nov 21 '22 at 23:26
  • 2
    Remember that `sizeof()` is a compile time constant. – drescherjm Nov 21 '22 at 23:35
  • 2
    Some comments on the code. Prefer to pass vectors and other potentially heavy structures by reference (or const reference). `vector_to_print.size()` could be taken apart as a variable, for making the code easier to read. And the second part of the `cout` can be simplified to `((i < s - 1) ? ", " : "\n")`. BTW, you can print standard containers using the `fmt` library. [Demo](https://godbolt.org/z/P4MK89vE7) – rturrado Nov 21 '22 at 23:42
  • 1
    `vector_to_print.size()` is correct. `sizeof(vector_to_print)` is not. There is no relationship between the values they produce. – Peter Nov 21 '22 at 23:45
  • thanks everyone for the replies rturrado do I have to make the vect...size() into a variable to make this work ((i < s - 1) ? ", " : "\n") if I just try changing my code to ((i < vector_to_print.size()-1) ? ", " : "\n" ); it doesn't work properly it prints the list out without any commas. – BrianDawe Nov 22 '22 at 00:16
  • 2
    As to `((i < vector_to_print.size()-1) ? ", " : "\n" )` not working ...... Bear in mind that `vector_to_print().size()` produces an *unsigned* integral result. If `vector_to_print.size()` produces `0`, then `vector_to_print.size() - 1` does not produce a negative value - it produces a large positive value of an unsigned type. – Peter Nov 22 '22 at 00:26
  • 1
    As of C++17 you can also use `std::size(vector_to_print)`. Note that this means using `using namespace std;` and anything named `size` can result in... trouble. [Trivial example](https://godbolt.org/z/fxdae8f3P). Note how none of the headers normally [tasked with providing `std::size`](https://en.cppreference.com/w/cpp/iterator/size) are directly included. Such is life. – user4581301 Nov 22 '22 at 00:30
  • I hadn't considered a 0 sized vector. Why would changing (cout << ", ") : (cout << endl) to ", " : "\n" break the cout? – BrianDawe Nov 22 '22 at 00:36
  • Is typing std:: preferred to using namespace std? – BrianDawe Nov 22 '22 at 00:37
  • 1
    Yes, read this: [https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice](https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice) – drescherjm Nov 22 '22 at 00:51
  • The sad truth about bugs: They're always something you didn't consider. If you had considered them, you'd have written different code. – user4581301 Nov 22 '22 at 01:37
  • *"Both seem to work"* -- really? When I tried the first one, I got a segmentation fault unless the vector had at least 24 entries, and in other cases at most 24 entries would print out. Which is pretty much the behavior I'd expect. Could you provide an example of how you tested the first example? – JaMiT Nov 22 '22 at 01:56
  • Related: [Size of vector returned by sizeof()](https://stackoverflow.com/questions/67218764/) – JaMiT Nov 22 '22 at 02:07
  • Thanks for all the advice and links I have a bit more reading to do which is always good. Jamit I made a vector vector carsVector then I pushed back 4 strings "ford" "merc" "bmw" "ferarri" and called the function printVector(carsVector); The code is on my PC at home I can upload it later (this is my laptop at work). – BrianDawe Nov 22 '22 at 08:24
  • @BrianDawe *"I pushed back 4 strings "ford" "merc" "bmw" "ferarri" and called the function printVector(carsVector);"* -- did you try to produce any output after this? Sometimes a seg fault occurs quietly, so if it occurs at the end of your program, you might mistake it for ending normally. Adding a line like `std::cout << "Done!\n";` at the end of your test might reveal that the test was not as successful as you thought. – JaMiT Nov 23 '22 at 00:51

2 Answers2

3

std::vector<std::string> is a container class, which stores an array of std::strings plus other values to assist with manipulation of the array and providing information about the state of the stored array. When you call sizeof(vector_to_print) you are simply getting the size of the container class not the amount of elements in the array that it is storing.

run the following code to prove it to yourself:

std::vector<std::string> vec{"hello","world"};
std::cout << sizeof(vec) << '\n';
vec.push_back("!");
std::cout << sizeof(vec);

the size of the underlying array is changing it goes from 2 elements to 3, but not only does the sizeof(vec) not change, it is always = to 24!

sizeof(vec) must be the same each time (24 bytes on my machine) because sizeof is a compile time constant, because the size of a type must be a compile time constant.

The latter (.size()) is the only valid method

wigi426
  • 91
  • 4
0

As you already know there are classes in C++. One class can have many methods doing different things and many fields holding different things. When we create an object of class Vector this object has method .size() which as mentioned here returns the number of elements in our object. The complexity is Constant and there is no problem using .size(). When you are using sizeof() as mentioned here on our object you know the size of the object with all its fields (for example vector can have size_t field where it counts all the elements and some field which holds them) you don't need the actual size of the vector in order to iterate the elements this could be wrong in many cases.

P.S. You must use .size()!

Usitha Indeewara
  • 870
  • 3
  • 10
  • 21
tedo3637
  • 37
  • 5