Reputation: 883
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
};
Upvotes: 1
Views: 3539
Reputation: 9820
The problem is in your constructor
Go like this for the constructor:
dynamic_array::dynamic_array() {
array = new int[4];
array[0] = 3;
size = 4;
allocated_size = 5;
}
the problem is this additinal line of code in the constructor:
int *array;
In your constructor definition, you declared a new local pointer variable named array and you allocated memory for that.
But this variable is local to the constructor and it is not the one declared in your class as may be you believed.
Upvotes: 1
Reputation: 145459
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.
Upvotes: 3