Can you tell why does this generate segmentation error? Problem seems to occur when operator[] is called and when I don't call it, goes fine. operator[] is supposed to return a reference to the element with index i.. any help would be great..
//dynamic_array.cpp file
#include <iostream>
#include "dynamic_array.h"
using namespace std;
dynamic_array::dynamic_array() {
int *array;
array=new int[4];
array[0]=3;
size = 4;
allocated_size = 5;
}
dynamic_array::~dynamic_array() {
delete [] array;
}
int dynamic_array::get_size(void) const {
return size;
}
int dynamic_array::get_allocated_size(void) const {
return allocated_size;
}
int& dynamic_array::operator[](unsigned int i) {
return array[i];
}
//test.cpp file
#include <iostream>
#include <stdlib.h>
#include "dynamic_array.h"
using namespace std;
int main() {
dynamic_array a;
cout << a[0];
}
//dynamic_array.h file
using namespace std;
class dynamic_array {
public:
enum {
BLOCK_SIZE = 5,
SUBSCRIPT_RANGE_EXCEPTION = 1,
MEMORY_EXCEPTION = 2,
};
dynamic_array();
~dynamic_array();
int get_size(void) const;
int get_allocated_size() const;
int& operator[](unsigned int i);
class exception {
public:
exception(int n0) { n = n0; };
int n;
};
private:
int *array; // pointer to dynamically allocated memory
int allocated_size; // total number of elements in allocated memory
int size; // number of active elements
};
The local declaration
int *array;
shadows the member array
. So the following code uses the local variable, not the member. Hence the member is uninitialized.
Instead of creating your own dynamic array, use std::vector
.
That's safer and more convenient.
In other news:
The get
prefix in e.g. get_size
is a Java-ism.
In C++ a get
prefix has no advantage, and it makes the code less readable. For example, standard library containers have a size
method, not a get_size
.
Using void
as a formal argument declaration, as in get_size(void)
, is a C-ism.
In C it has the important effect of telling the compiler that there really are no arguments, as opposed to any arguments. In C++ ()
indicates that.
Not having also a const
version of operator[]
is inconsistent with earlier use of const
.
Consistency is very important in programming. Our expectation, e.g. when maintaining code, is that it's consistent. Code that's inconsistent adds costly man-hours to maintenance.
The ALL UPPERCASE
identifiers for constants are a Java-ism.
Java lacks a preprocessor, and inherited the all uppercase convention from early C, which lacked const
. C++ has both const
and a preprocessor. Having const
there's generally no need to use #define
for constants (as in early C), and having a preprocessor there's a good tecnical reason to not use all uppercase (it conflicts with the convention for macro names). In addition many/most programmers see all uppercase as shouting. It hurts.
The class exception
should better be derived from std::exception
.
Instead of inventing one's own exception class that can carry an error code, just use std::system_error
. That's what it's for. Alternatively, derive a class from std::runtime_error
, or use std::runtime_error
directly.