[c++] Correct way of looping through C++ arrays

Recently I have found a lot of examples, most of them regards the C++ 98, anyways I have created my simple-array and a loop (codepad):

#include <iostream>
using namespace std;

int main ()
{
   string texts[] = {"Apple", "Banana", "Orange"};
   for( unsigned int a = 0; a < sizeof(texts); a = a + 1 )
   {
       cout << "value of a: " << texts[a] << endl;
   }

   return 0;
}

Output:

value of a: Apple
value of a: Banana
value of a: Orange

Segmentation fault

It's working fine, except the segmentation fault at the end.

My question is, does this array/loop through is done a good way? I am using C++ 11 so would like to be sure it fits the standards and couldnt be done a better way?

This question is related to c++ arrays loops c++11

The answer is


In C/C++ sizeof. always gives the number of bytes in the entire object, and arrays are treated as one object. Note: sizeof a pointer--to the first element of an array or to a single object--gives the size of the pointer, not the object(s) pointed to. Either way, sizeof does not give the number of elements in the array (its length). To get the length, you need to divide by the size of each element. eg.,

for( unsigned int a = 0; a < sizeof(texts)/sizeof(texts[0]); a = a + 1 )

As for doing it the C++11 way, the best way to do it is probably

for(const string &text : texts)
    cout << "value of text: " << text << endl;

This lets the compiler figure out how many iterations you need.

EDIT: as others have pointed out, std::array is preferred in C++11 over raw arrays; however, none of the other answers addressed why sizeof is failing the way it is, so I still think this is the better answer.


sizeof tells you the size of a thing, not the number of elements in it. A more C++11 way to do what you are doing would be:

#include <array>
#include <string>
#include <iostream>

int main()
{
    std::array<std::string, 3> texts { "Apple", "Banana", "Orange" };
    for (auto& text : texts) {
        std::cout << text << '\n';
    }
    return 0;
}

ideone demo: http://ideone.com/6xmSrn


sizeof(texts) on my system evaluated to 96: the number of bytes required for the array and its string instances.

As mentioned elsewhere, the sizeof(texts)/sizeof(texts[0]) would give the value of 3 you were expecting.


Add a stopping value to the array:

#include <iostream>
using namespace std;

int main ()
{
   string texts[] = {"Apple", "Banana", "Orange", ""};
   for( unsigned int a = 0; texts[a].length(); a = a + 1 )
   {
       cout << "value of a: " << texts[a] << endl;
   }

   return 0;
}

How about:

#include <iostream>
#include <array>
#include <algorithm>

int main ()
{
    std::array<std::string, 3> text = {"Apple", "Banana", "Orange"};
    std::for_each(text.begin(), text.end(), [](std::string &string){ std::cout << string << "\n"; });

    return 0;
}

Compiles and works with C++ 11 and has no 'raw' looping :)


string texts[] = {"Apple", "Banana", "Orange"};
for( unsigned int a = 0; a < sizeof(texts); a = a + 1 )
{
    cout << "value of a: " << texts[a] << endl;
}

Nope. Totally a wrong way of iterating through an array. sizeof(texts) is not equal to the number of elements in the array!

The modern, C++11 ways would be to:

  • use std::array if you want an array whose size is known at compile-time; or
  • use std::vector if its size depends on runtime

Then use range-for when iterating.

#include <iostream>
#include <array>


int main() {
    std::array<std::string, 3> texts = {"Apple", "Banana", "Orange"};
    // ^ An array of 3 elements with the type std::string

    for(const auto& text : texts) {   // Range-for!
        std::cout << text << std::endl;
    }
}

Live example


You may ask, how is std::array better than the ol' C array? The answer is that it has the additional safety and features of other standard library containers, mostly closely resembling std::vector. Further, The answer is that it doesn't have the quirks of decaying to pointers and thus losing type information, which, once you lose the original array type, you can't use range-for or std::begin/end on it.


If you have a very short list of elements you would like to handle, you could use the std::initializer_list introduced in C++11 together with auto:

#include <iostream>

int main(int, char*[])
{
    for(const auto& ext : { ".slice", ".socket", ".service", ".target" })
        std::cout << "Handling *" << ext << " systemd files" << std::endl;

    return 0;
}

You can do it as follow:

#include < iostream >

using namespace std;

int main () {

   string texts[] = {"Apple", "Banana", "Orange"};

   for( unsigned int a = 0; a < sizeof(texts) / 32; a++ ) { // 32 is the size of string data type

       cout << "value of a: " << texts[a] << endl;

   }


   return 0;

}

you need to understand difference between std::array::size and sizeof() operator. if you want loop to array elements in conventional way then you could use std::array::size. this will return number of elements in array but if you keen to use C++11 then prefer below code

for(const string &text : texts)
    cout << "value of text: " << text << endl;

Examples related to c++

Method Call Chaining; returning a pointer vs a reference? How can I tell if an algorithm is efficient? Difference between opening a file in binary vs text How can compare-and-swap be used for a wait-free mutual exclusion for any shared data structure? Install Qt on Ubuntu #include errors detected in vscode Cannot open include file: 'stdio.h' - Visual Studio Community 2017 - C++ Error How to fix the error "Windows SDK version 8.1" was not found? Visual Studio 2017 errors on standard headers How do I check if a Key is pressed on C++

Examples related to arrays

PHP array value passes to next row Use NSInteger as array index How do I show a message in the foreach loop? Objects are not valid as a React child. If you meant to render a collection of children, use an array instead Iterating over arrays in Python 3 Best way to "push" into C# array Sort Array of object by object field in Angular 6 Checking for duplicate strings in JavaScript array what does numpy ndarray shape do? How to round a numpy array?

Examples related to loops

How to increment a letter N times per iteration and store in an array? Angular 2 Cannot find control with unspecified name attribute on formArrays What is the difference between i = i + 1 and i += 1 in a 'for' loop? Prime numbers between 1 to 100 in C Programming Language Python Loop: List Index Out of Range JavaScript: Difference between .forEach() and .map() Why does using from __future__ import print_function breaks Python2-style print? Creating an array from a text file in Bash Iterate through dictionary values? C# Wait until condition is true

Examples related to c++11

Remove from the beginning of std::vector Converting std::__cxx11::string to std::string What exactly is std::atomic? C++ How do I convert a std::chrono::time_point to long and back Passing capturing lambda as function pointer undefined reference to 'std::cout' Is it possible to use std::string in a constexpr? How does #include <bits/stdc++.h> work in C++? error::make_unique is not a member of ‘std’ no match for ‘operator<<’ in ‘std::operator