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 animated GIF below shows the code being compiled and run:

Why did the program crash when we tried to get statistics for files with 500 or 500,000 numbers?

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 bus error 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

    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!

If you think about what we've seen already in the class, we know enough that we could make our own type that feels just like a primitive array, but without the limitations. Our CheckList class from the previous lesson came very close, but didn't automatically resize the array size. Thanks to the dynamic-train assignment we now know how to do resizing by doubling the capacity of our array when we run out of space.

While we could write our own resizing function, C++ has us covered. The C++ standard provides a full-featured alternative to primitive arrays—std::vector—that is much easier to use than primitive arrays.

  • 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.

  • Pig speaking

    I want to know MORE about std::vector!

  • LHS Cow speaking

    Coming right up!

(When logged in, completion status appears here.)