1

I'm trying to write a program which handles matrices and arrays. Thus, I wrote the following code:

Array.h

#ifndef _ARRAY_H_
#define _ARRAY_H_

class Array{
    private:
        int * data;
        int length;

public:
    Array();
    Array(int size);
    ~Array();

    void set(int pos, int value);
    int get(int pos);
    void print();

    /*works only for arrays of length 9*/
    static int find_max(int data[]);
};
#endif

Array.cpp

#include <iostream>
#include <stdlib.h>
#include <string.h>
#include "Array.h"

using namespace std;

Array::Array(){
    Array(10);
}

Array::Array(int size){
    data = new int[size];
    memset(data, 0, sizeof(data));
    length = size;
}

Array::~Array(){
    delete [] data;
}

...

/*works only for arrays of length 9*/
int Array::find_max(int data[]){
    int max = data[0];

    for(int i = 1; i < 9; i++){
        if(data[i] > max) max = data[i];
    }

    return max;
}

Matrix.h

#ifndef _MATRIX_H_
#define _MATRIX_H_
#include "Array.h"

class Matrix{

    private:
        Array * data;
        int height;
        int width;

    public:
        Matrix();
        Matrix(int _height, int _width);
        ~Matrix();

        void set(int h, int w, int value);
        int get(int h, int w);
        void print();
};

#endif

Matrix.cpp

#include <iostream>
#include <stdlib.h>
#include <string.h>
#include "Matrix.h"

using namespace std;

Matrix::Matrix(){
    Matrix(10, 10);
}

Matrix::Matrix(int _height, int _width){
    height = _height;
    width = _width;

    data = (Array*)malloc(sizeof(Array)*height);

    for(int i = 0; i < height; i++){
        Array * row = new Array(width);
        *(data + i) = *row;
    }
}

 ...

void Matrix::print(){
    for(int i = 0; i < height; i++){
        Array row = *(data + i);
        row.print();
    }
    return;
}

main.cpp

#include <iostream>
#include <stdlib.h>
#include <string.h>
#include "Array.h"
#include "Matrix.h"

using namespace std;

int main(int argc, char** argv){
    if(argc != 3){
        cout << "usage: " << argv[0] << " <m> x <n>" << endl;
    }

    int m = atoi(argv[1]);
    int n = atoi(argv[2]);

    Matrix myMatrix(m, n);

    /*fill matrix randomly*/
    int guess, minus;
    srand(time(NULL));

    for(int r = 0; r < m; r++){
        for(int c = 0; c < n; c++){
            guess = rand() % 1001;
            minus = rand() % 2;

            if(minus == 0) guess *= -1;
            myMatrix.set(r, c, guess);;

        }
    }

    cout << "randomly created matrix" << endl;
    myMatrix.print();

    /*find local maximum and print it in another matrix*/
    Matrix localMaxMatrix(m, n);

    for(int r = 0; r < m; r++){
        for(int c = 0; c < n; c++){
            /*correct access is ensured within get method*/
            int values[] = {myMatrix.get(r-1, c-1),
                            myMatrix.get(r-1, c),
                            myMatrix.get(r-1, c+1),
                            myMatrix.get(r,   c-1),
                            myMatrix.get(r,   c),
                            myMatrix.get(r,   c+1),
                            myMatrix.get(r+1, c-1),
                            myMatrix.get(r+1, c),
                            myMatrix.get(r+1, c+1)};
            localMaxMatrix.set(r, c, Array::find_max(values));
        }
    }

    cout << "----------------------------------------" << endl;
    cout << "local max for each entry of above matrix" << endl;
    localMaxMatrix.print();

    return 0;
}

Compiling it with c++ -Wall -pedantic -o matrix Array.cpp Matrix.cpp results in the following compile error:

/usr/lib/gcc/i686-pc-cygwin/4.5.3/../../../libcygwin.a(libcmain.o): In function 'main': /usr/src/debug/cygwin-1.7.17-1/winsup/cygwin/lib/libcmain.c:39: undefined reference to '_WinMain@16'

What is the problem with my code and how am I supposed to compile my files correctly (not using any makefiles)? Thanks!

kafman
  • 2,862
  • 1
  • 29
  • 51
  • 1
    I think you forgot to add main.cpp along with Array.cpp and Matrix.cpp. The while compile string should be something like `c++ -Wall -pedantic -o matrix Array.cpp Matrix.cpp main.cpp` – olevegard May 05 '13 at 19:10
  • 3
    Read this and abide by it: http://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-a-c-identifier – chris May 05 '13 at 19:24
  • Linker errors that start with *undefined reference* indicate that the symbol in the error message is not in the executable: it either was not defined, or it was defined but the translation unit that contains the symbol was not added to the linker command line. – David Rodríguez - dribeas May 05 '13 at 19:41
  • 1
    This isn't the problem, but names that begin with an underscore followed by a capital letter (`_ARRAY_H_`) and names that contain two consecutive underscores are reserved to the implementation. Don't use them. – Pete Becker May 05 '13 at 19:56

1 Answers1

4

Add "main.cpp" to your compile line:

$ c++ -Wall -pedantic -o matrix Array.cpp Matrix.cpp main.cpp
                                                     ^^^^^^^^
Andrew Tomazos
  • 66,139
  • 40
  • 186
  • 319
  • How can I not have seen this?! Thanks! It does compile now, but I the program aborts and in the debugger I get the messages "glibc detected ... Program received signal SIGABRT, Aborted. 0xb7fdd424 in __kernel_vsyscall ()" But I don't know if this is related to the way I compiled the program ... – kafman May 05 '13 at 19:27
  • 1
    @StringerBell: The error message probably told you what glibc detected, which is the important bit in the error. That is, the fact that it detected something is good, but knowing what it detected is important to find what the error was [Most probably it detected a double free?] There are a few things wrong in your program, but you should open separate questions: for example, the default `Array` constructor does not do what you may think (it does not forward the call to the 1 arg constructor if that is what you expected) – David Rodríguez - dribeas May 05 '13 at 19:42
  • @DavidRodríguez-dribeas Ok thank you, I will have a look at this again and treat these problems in separate questions if necessary. – kafman May 05 '13 at 19:55