CS 70

A Simple Program Using Primitive Arrays

This program reads in a list of numbers from std::cin, and then calculates a few statistics about them.

#include <iostream>
#include <algorithm>

int main() {
    double values[100];
    size_t numValues = 0;

    while (true) {
        double value;
        std::cin >> value;
        if (!std::cin.good()) {
            break;
        }
        values[numValues] = value;
        ++numValues;
    }

    double total = 0.0;
    for (auto p = values; p != values+numValues; ++p) {
        total += *p;
    }

    std::cout << "Read " << numValues << " values" 
              << ", total " << total
              << ", average " << total/numValues << std::endl;

    std::sort(values,values+numValues);
    std::cout << "Min is " << values[0]
              << ", max is " << values[numValues-1]
              << ", median is " << values[numValues/2] << std::endl;

    return 0;
}

The ASCII-cast below shows the program being compiled and run:

Like a video, you can pause, rewind, and replay the ASCII-cast as often as you like.

Why did the program crash when we tried to get statistics for files with 500 or 500,000 numbers? Also, what's an interesting difference between the two crashes?

Our code set a fixed size for the array (100 elements), so if our program tries to read more elements than that limit at runtime, it goes out of bounds, attempting to read memory outside the array.

When our code tried to read 500 elements from its 100-element array, it caused a segmentation fault because it corrupted the stack, which caused problems for the hidden system function that called main.

When we tried to make our code read 50,000 elements from its 100-element array, the program not only overran the stack, but attempted to access memory outside the bounds of the memory it was given by the operating system, causing a segmentation fault error.

  • Goat speaking

    Meh. This is why I don't like C++. These stupid limitations like fixed sizes for arrays. It was so much easier in Python.

  • Python speaking

    Actually, Python is written in C. But, yes, we hide all that stuff.

  • LHS Cow speaking

    And C++ can hide it all, too! That's exactly what you did in the CoordVector class in the Maze assignment.

The C++ standard provides a full-featured alternative to primitive arrays—std::vector—that is much easier to use, just like the CoordVector class you wrote in the Maze assignment, but working on any type of data, not just Coords.

  • Hedgehog speaking

    Whaaat??? Why did I go through all the pain of using primitive arrays, figuring out new and delete, and all that stuff?

  • Bjarne speaking

    It is part of our heritage.

  • LHS Cow speaking

    That's not really the reason.

Why did we learn all that other stuff and not just use std::vector, given that it apparently makes everything so much easier?

CS 70 is about understanding how data structures work (learning C++ is a secondary goal). When you have arrays that can hold arbitrary numbers of things, growing as needed, something has to happen to make that possible. You've seen enough by now to understand how that all works behind the scenes and in your code.

  • RHS Cow speaking

    In fact, in some ways our CoordVector class was friendlier than std::vector, because it also allowed efficiently pushing and popping from the front of the vector, which std::vector doesn't support, allowed Python-like negative indexing, and threw exceptions when you tried to access out-of-bounds elements, instead of admonishing you to be careful to stay in bounds and taking a “whatever happens, happens” attitude if you make a mistake.

  • Bjarne speaking

    Actually, std::vector does have a .at() member function that throws exceptions on out-of-bounds access, but it's not the default way to access elements.

  • Pig speaking

    I want to know MORE about std::vector!

  • LHS Cow speaking

    Coming right up!

(When logged in, completion status appears here.)