0

I am trying to get this simple program to work but I have some errors I don't understand as I am new to C++. I am getting a not declared in scope for my function initialize and am having trouble using arrays in the function header. Can someone help me please?

My code is the following:

#include <iostream>
#include <string>
using namespace std;

char[][] initialize(char[][]);

int main(){

    int array[3][3];
    initialize(array);

    cout << array[0];

    return 0;
}

char[][] initialize(char[][] a){

    for(int i = 0; i < a.length(); i++){
        for(int j = 0; j < a[].length(); j++){
            a[i][j] = '\0';
        }
    }

    return a;

}
  • 2
    There's no `length()` information or function for raw arrays. Use `std::vector` (and `size()`) instead. – πάντα ῥεῖ Oct 19 '15 at 19:21
  • That is not my main problem at the moment. I am getting a not declared in scope for my function initialize and and error reading expected unqualified-id before ‘[’ token. Any ideas on why these two errors occur and how to fix them? – user3540561 Oct 19 '15 at 19:27
  • 1
    `char[][] initialize(char[][]);` is not a valid declaration, so it is rejected. Naturally, that will also cause a "not declared" error when you try to call the function. One error causes the next. – Bo Persson Oct 19 '15 at 19:31
  • 1
    Passing around 2D arrays is tricky. Rule of thumb is don't. If you can't use a `std::vector`, make your own small wrapper and pass it around instead. – user4581301 Oct 19 '15 at 19:54

4 Answers4

1

You could initialize your 2d array elements to \0 simply by:

char array[3][3] = {0};

Now if you want to pass your array to a function (e.g., print_2d_array()), and in order to have the dimensions of your 2d array you need to pass your array by reference in the following manner:

template<typename T, std::size_t N, std::size_t M>
void print_2d_array(T (&a)[N][M]){

    for(int i = 0; i < N; ++i){
        for(int j = 0; j < M; ++j){
            std::cout << a[i][j] << " ";
        }
        std::cout << std::endl;
    }
}

The above function prints an arbitrary type/dimensions 2d array.

101010
  • 41,839
  • 11
  • 94
  • 168
1

If you have fixed-size arrays, you can (and should) use std::array instead of raw C-style arrays. I will use you initialize function as an example, although there are other ways to initialize the array.

#include <iostream>
#include <string>
#include <array>
using namespace std;

void initialize(std::array<std::array<char, 3>, 3>&);

int main(){

    std::array<std::array<char, 3>, 3> array{};
    initialize(array);

    return 0;
}

void initialize(std::array<std::array<char, 3>, 3>& a) {
    for(auto& outer: a) {
        for(auto& x: outer) {
             x = '\0';
        }
    }
}

Of course if you want to work with arrays of strings, and this is what I think you actually want, you should do so and use std::string instead of zero-terminated C-style strings.

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


int main(){

    std::array<std::string, 3> array{};
    array.fill( std::string(3, '\0') );

    std::cout << array[0];

    return 0;
}

The initialization is not necessary in this case since std::string is correctly initialized by its constructor.

If you need dynamic storage, you should use a std::vector instead of std::array. In any case, my advice would be to use the type-safe and way more convenient C++ tools instead of the error-prone and - frankly - painfully to use C equivalents.

Jens
  • 9,058
  • 2
  • 26
  • 43
  • 1
    Best answer by far. Two things: due to a bug in GCC, `array{};` needs to be `array{{}};` if compiled with g++ and `array{};` makes the `initialize` function redundant. – user4581301 Oct 19 '15 at 22:35
0

Since you know the size of array and passing array by reference so no need to return array:

void initialize(char[][3]);//declaration

Function:

void initialize(char a[][3]){
//no such function as array.lenth()
for(int i = 0; i < 3; i++){
    for(int j = 0; j <3; j++){
        a[i][j] = '\0';
    }
}

Also i can see you have declared an integer array and passed to a char array.So either have an integer array or char array but not both.

wrangler
  • 3,454
  • 1
  • 19
  • 28
0

Trick one: Save yourself the trouble of forward declaring initialize by placing the function definition ahead of main. This eliminates one potential source of errors.

Trick two: Jens beat me to. Use std::array.

Trick three: Use std::vector.

#include <iostream>
#include <string>
#include <vector>
//using namespace std; this can be dangerous. Recommend the following as a replacement
using std::vector;
using std::cout;

void initialize(vector<vector<char>> &a) // pass vector by reference 
{   
    for(int i = 0; i < a.size(); i++)
    {   
        for(int j = 0; j < a[i].size(); j++)
        {   
            a[i][j] = '\0';
        }
    }
}

int main()
{
    vector<vector<char>> array(3, vector<char>(3));
    initialize(array);

    cout << array[0][0];

    return 0;
}

Two points to make here

  1. This has performance problems. A vector of vectors (or an array of arrays) is unlikely to have contiguity (memory all in one block) and will cause unnecessary delays loading array data from RAM to cache. If all the data is close together, and small enough to fit, one cache read will get the whole array. If it is scattered, each piece needs to be read separately and loading one piece may overwrite another forcing it to be loaded again (which may write over another piece of memory needed a few instructions latter, forcing it to be re-read as well and this may force the other piece or yet another piece out, ad infinitum. This is called Cache Thrashing.

  2. std::vector can initialize the array contents for you

Need text here for some reason to preserve the formatting of the next code block. Weird.

int main()
{
    vector<vector<char>> array(3, vector<char>(3), '\0');
    cout << array[0][0];

    return 0;
}

And if because of assignment restriction you are not allowed to use std::array or std::vector, a trivial clone of std::array is easy to write.

struct TwoD
{
    char array[3][3];
    char &operator()(int row, int col)
    {
        return array[row][col];
    }
};

is probably all you need.

user4581301
  • 33,082
  • 7
  • 33
  • 54