c++ - ==15341==ERROR: AddressSanitizer: heap-buffer-overflow on address 0xb59007e0 at pc 0x8048ca7 bp 0xbfb47388 sp 0xbfb4737c -


i'm pretty new dynamic memory management , using fsanitise flag find problems memory management. cannot use vector store data - need use primitive arrays, "new" , "delete" manage heap objects.

i got following error when try run euclideanvectortester compiled program not sure problem is, enlighten me please?

weill % make g++ -std=c++14 -wall -werror -o2 -fsanitize=address -c euclideanvectortester.cpp g++ -std=c++14 -wall -werror -o2 -fsanitize=address -c euclideanvector.cpp g++ -fsanitize=address euclideanvectortester.o euclideanvector.o -o euclideanvectortester weill % ./euclideanvectortester 1 ================================================================= ==15341==error: addresssanitizer: heap-buffer-overflow on address 0xb59007e0 @ pc 0x8048ca7 bp 0xbfb47388 sp 0xbfb4737c write of size 8 @ 0xb59007e0 thread t0     #0 0x8048ca6 in main (/tmp_amd/kamen/export/kamen/3/z3386180/cs6771/evec/euclideanvectortester+0x8048ca6)     #1 0xb6ecae45 in __libc_start_main (/lib/i386-linux-gnu/i686/cmov/libc.so.6+0x16e45)  0xb59007e0 located 0 bytes right of 16-byte region [0xb59007d0,0xb59007e0) allocated thread t0 here:     #0 0xb722a4c4 in operator new[](unsigned int) (/usr/lib/libasan.so.1+0x524c4)     #1 0x8048b9a in main (/tmp_amd/kamen/export/kamen/3/z3386180/cs6771/evec/euclideanvectortester+0x8048b9a)     #2 0xb6ecae45 in __libc_start_main (/lib/i386-linux-gnu/i686/cmov/libc.so.6+0x16e45)     #3 0x8048d8c (/tmp_amd/kamen/export/kamen/3/z3386180/cs6771/evec/euclideanvectortester+0x8048d8c)  summary: addresssanitizer: heap-buffer-overflow ??:0 main shadow bytes around buggy address:   0x36b200a0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa   0x36b200b0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa   0x36b200c0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa   0x36b200d0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa   0x36b200e0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa =>0x36b200f0: fa fa fa fa fa fa fa fa fa fa 00 00[fa]fa 04 fa   0x36b20100: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa   0x36b20110: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa   0x36b20120: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa   0x36b20130: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa   0x36b20140: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa shadow byte legend (one shadow byte represents 8 application bytes):   addressable:           00   partially addressable: 01 02 03 04 05 06 07    heap left redzone:       fa   heap right redzone:      fb   freed heap region:       fd   stack left redzone:      f1   stack mid redzone:       f2   stack right redzone:     f3   stack partial redzone:   f4   stack after return:      f5   stack use after scope:   f8   global redzone:          f9   global init order:       f6   poisoned user:        f7   contiguous container oob:fc   asan internal:           fe ==15341==aborting weill % 

the euclideanvector.h file this:

#ifndef _euclideanvector_h #define _euclideanvector_h  #include <iostream> #include <algorithm>   namespace {     class euclideanvector {          public:              /*              * constructor takes number of dimensions (as unsigned int) no magnitudes,               * sets magnitude in each dimension 0.0. default constructor, default value being 1.              */             template <typename num>             euclideanvector(const num dimensions = 1):                    euclideanvector(dimensions, 0.0) {}; // delegating constructor; default constructor takes in dimensions if there user input, otherwise dimensions = 1 if empty constructor              // target constructor delegating constructor             template <typename num1, typename num2> // numeric types of user input dimensions , magnitude static_cast unsigned int , double respectively             euclideanvector(const num1 dimensions, const num2 magnitude){                          // static cast unsigned int , assign dimensions_                         dimensions_ = new unsigned int (static_cast<unsigned int>(dimensions));                          // assign pointer "magnitude_" dynamically-allocated memory of new unnamed array<double> object of size "dimensions_"                         magnitude_  =  new double [*dimensions_];                          // fill array<double> object "magnitude_" number of "dimensions_" times, <double> value of "magnitude_" each dimension                         std::fill_n(magnitude_, dimensions_, static_cast<double>(magnitude));                    }              /*              * destructor: ~euclideanvector              * destructor deallocates memory acquired constructors.               */             ~euclideanvector();               /*              * member function: getmagnitude()              * returns double containing number of dimensions in particular array.              */             const double& getmagnitude () const;               /*              * member function: getnumdimensions()              * returns unsigned int containing number of dimensions in particular vector.              */             unsigned int getnumdimensions() const;           private:         /* here end of class private,          * not accessible or intended use client */              unsigned int *dimensions_;             double *magnitude_;             //double normal_;         }; }  #endif 

the euclideanvector.cpp file this:

#include "euclideanvector.h" #include <algorithm> #include <cmath> // sqrt #include <sstream> #include <iterator>  namespace {      unsigned int euclideanvector::getnumdimensions () const     {         return *dimensions_;     }      const double& euclideanvector::getmagnitude () const     {         return *magnitude_;     }      // destructor     euclideanvector::~euclideanvector() {         delete dimensions_;         delete [] magnitude_;     } } 

and euclideanvectortester.cpp file this:

#include <iostream> #include <vector> #include <list>  #include "euclideanvector.h"  int main() {      std::cout << "1" << std::endl;      evec::euclideanvector a(2);        std::cout << "2" << std::endl;     std::cout << "3" << std::end;  } 

let me professor states has lot of inaccuracies (to least).

having said that, issue you've declared dimensions unsigned int*, yet you're using if plain unsigned int here:

std::fill_n(magnitude_, dimensions_, static_cast<double>(magnitude)); 

the immediate fix this:

std::fill_n(magnitude_, *dimensions_, static_cast<double>(magnitude)); 

however, begs question of why simple unsigned int needs pointer, , allocated using new. there no reason this, using new less efficient you're doing now.

if had declared dimensions_ this:

unsigned int dimensions_; 

instead of being pointer, code assign dimensons_ becomes this:

// no call new done dimensions_ = static_cast<unsigned int>(dimensions);  // no dereference of pointer needs done on 2 lines below  magnitude_ = new double[dimensions_]; std::fill_n(magnitude_, dimensions_, static_cast<double>(magnitude)); 

no additional call allocator done, code instantly becomes more efficient.

in addition, destructor this:

euclideanvector::~euclideanvector()  {     delete magnitude_; } 

but of stated, answer given fixes issue if use same main program test with. if changed main this:

even::euclideanvector a(2); even::euclideanvector b = a; 

you run copy semantics being incorrect. again, fix above required make main function work. change main simple above example, , run more issues.


Comments

Popular posts from this blog

amazon web services - S3 Pre-signed POST validate file type? -

c# - Check Keyboard Input Winforms -