-2

Right now i'm trying to get my code(simple POD containers) running as stable as humanly possible. My main concern is memory allocation and deallocation(new[] and delete[] operators). Is it possible to get any undesired behavior out of them(like SIGSEGV or exceptions)? Here's a little test example i wrote:

class my_vector{
    private:
        long* _data;
        size_t _size;
        size_t _capacity;
    public:
        my_vector()
       {
           this->_data = new long[10];
           this->_size = 0;
           this->_capacity = 10;
       };

        ~my_vector()
       {
           delete[] this->_data;
       };

        void add(long value)
       {
           if (this->_size == this->_capacity)
                 this->expand();
           this->_data[this->_size] = value;
           this->_size++;
       };
    private:
        void expand()
        {
           long* tmp = new long[this->_capacity*2];
           memcpy(tmp, this->_data, sizeof(long)*this->_size);
           this->_capacity *= 2;
           delete[] this->_data;
           this->_data = tmp;
        };
}
grango
  • 17
  • 3
  • Please read or review [the help pages](http://stackoverflow.com/help), especially ["What topics can I ask about here?"](http://stackoverflow.com/help/on-topic) and ["What types of questions should I avoid asking?"](http://stackoverflow.com/help/dont-ask). Also take the [tour] and read about [ask] good questions and [this question checklist](https://codeblog.jonskeet.uk/2012/11/24/stack-overflow-question-checklist/). – Some programmer dude Sep 20 '20 at 00:21
  • If you check that the alocations are succesfull, and dont delete data that is not yours, you should have no problems. When you allocate here: `this->_data = new long[10];` you dont check if the allocation was succesfull. And, if you copy any object from this class, you will get in some serious problems. I would recomend you to: 1. Check if the allocations where succesfull and 2. Follow the [The rule of three/five/zero](https://en.cppreference.com/w/cpp/language/rule_of_three). If you do both, you should have no problems at all. Take a look into smart pointers, that might help – Pablochaches Sep 20 '20 at 00:33
  • @Pablochaches - `this->_data = new long [10]` will throw an exception if it fails. That doesn't need to be checked (although the exception will eventually need to be caught, otherwise the program will terminate). – Peter Sep 20 '20 at 04:26

1 Answers1

0

A new[] expression, by default, throws an exception if it fails (e.g. if a dynamic memory allocation fails).

If the constructor of any of the objects being constructed fails by throwing an exception, then the new [] expression will have the (net) effect of throwing that exception. Some other things also happen before the exception is finally emitted - for example, if construction of the third object in a dynamically allocated array fails, the destructors for the two previously constructed objects will be called. As far as calling code is concerned, if an exception is emitted, then none of the objects created by the new[] expression have ever existed. This is specified in the standard.

If an exception is thrown and never caught, the program will terminate. That is normal and expected.

A delete [] expression will generally not throw unless a destructor of an object being destroyed throws. Defining a destructor which throws is usually considered very poor practice, so should be avoided.

There is a nothrow form of a new expression, that does not - in itself - throw exceptions. In that case, the new expression gives a null pointer on failure.

new[] and delete [] expressions do not, in themselves, cause SIGSEGV, or any other form of abnormal termination. If that occurs, it is a sign that some other code has exhibited undefined behaviour (e.g. written past the end of an array). That can be in the constructor or destructor of the objects in the array, or in other code.

Peter
  • 35,646
  • 4
  • 32
  • 74