Printing unexpected blank lines and crash - c++

For a school project I need to make a constructor with a recursive sort function that is given from a teacher in it, with a few function that I had to make myself. When I start the program the result shows a few blank lines and then the expected output. But when I increase int_buffer a(100) or higher and trys again the program just crashes. I think it might be memory leak, but not quite sure and don't know how to fix the problem either. I think that the problem is in int_sorted.cpp
Code:
main.cpp:
#include "int_buf.h"
#include "int_sorted.h"
#include <iostream>
#include <string>
void f(int_buffer& buf){
for (int* i = buf.begin();i != buf.end();i++) {
}
for (const int* i = buf.begin(); i != buf.end(); i++) {
}
}
int main(){
int_buffer a(100);
int_buffer b(50);
int r[] = {1,4,10,2,54,3,6,20};
for (size_t i = 0; i < a.size(); i++){
a[i] = std:: rand();
b[i] = std::rand();
}
int_sorted x(a.begin(), a.size());
}
std::cout << "\n";*/
for (int i = 0; i < x.size();i++) {
std::cout<<*(x.begin() + i)<<"\n";
return 0;
}
int_buf.h:
#ifndef INT_BUF_H
#define INT_BUF_H
#include <cstdlib>
class int_buffer {
public:
bool check_sorted(int_buffer int_check);
explicit int_buffer(size_t size);
int_buffer(const int * source, size_t size);
int_buffer(const int_buffer & rhs);
int_buffer(int_buffer && rhs);
int_buffer & operator =(const int_buffer & rhs);
int_buffer & operator =(int_buffer && rhs);
int& int_buffer::operator[](size_t index);
size_t size() const;
int * begin();
int * end();
const int* begin() const;
const int* end() const;
~int_buffer();
private:
size_t sz;
int* buf;
};
#endif
int_buf.cpp:
#include "int_buf.h"
#include <algorithm>
#include <iostream>
#include <cstddef>
bool int_buffer::check_sorted(int_buffer int_check){
int* a = int_check.begin();
int* b = nullptr;
while (a != int_check.end() -1){
b= a + 1;
if (*a > *b){
return false;
}
else{
a = b;
}
}
return true;
}
int_buffer::int_buffer(size_t size) :sz(size), buf(new int[size]){}
int_buffer::int_buffer(const int* source, size_t size) : sz(size), buf(new int[size]){
for (size_t i = 0; i < sz;i++){
buf[i] = *(source+i);
}
}
int_buffer::int_buffer(const int_buffer& rhs):sz(rhs.sz),buf(new int[rhs.sz]){
std::copy(rhs.begin(), rhs.end(), begin());
}
int_buffer::~int_buffer(){
delete[] buf;
}
int_buffer::int_buffer(int_buffer && rhs) :buf(nullptr), sz(0){
std::swap(buf, rhs.buf);
std::swap(sz, rhs.sz);
}
int_buffer& int_buffer::operator =(const int_buffer & rhs){
int_buffer temp(rhs);
std::swap(temp.buf,buf);
std::swap(temp.sz,sz);
return *this;
}
int_buffer & int_buffer::operator =(int_buffer&& rhs){
std::swap(buf, rhs.buf);
std::swap(sz, rhs.sz);
return *this;
}
int& int_buffer::operator[](size_t index){
return buf[index];
}
size_t int_buffer::size() const{
return sz;
}
int* int_buffer::begin(){
return buf;
}
int* int_buffer::end(){
return buf + sz;
}
const int* int_buffer::begin() const{
return buf;
}
const int* int_buffer::end() const{
return buf + sz;
}
int_sorted.h:
#ifndef INT_SORTED_H
#define INT_SORTED_H
#include "int_buf.h"
#include <iostream>
class int_sorted{
public:
int_sorted(const int* source, std::size_t size);
std::size_t size() const;
int* insert(int value);
const int* begin() const;
const int* end() const;
int_sorted merge(const int_sorted& merge_with) const;
int_sorted sort(const int*begin, const int* end);
void int_sorted::selSort(int_sorted& arr, int size);
private:
int_buffer buffer;
};
#endif
int_sorted.cpp:
#include "int_sorted.h"
#include "int_buf.h"
#include <iostream>
#include <algorithm>
#include <cstddef>
int_sorted::int_sorted(const int* source, size_t size) :buffer(source, size){
if (buffer.size() < 1) {}
else {
if (buffer.check_sorted(buffer)) {}
else {
int_buffer tmp(buffer.begin(), 0);
tmp = sort(buffer.begin(), buffer.end()).buffer;
buffer = tmp;
}
}
}
size_t int_sorted::size() const{
return buffer.size();
}
int* int_sorted::insert(int value) {
int_buffer tmp(buffer.size()+1);
for (int i =0; i < buffer.size();i++) {
tmp[i] = buffer[i];
}
tmp[buffer.size()] = value;
this->buffer = tmp;
return (buffer.end()-1);
}
const int* int_sorted::begin() const{
return buffer.begin();
}
const int* int_sorted::end() const{
return buffer.end();
}
int_sorted int_sorted::merge(const int_sorted& merge_with) const{
int_sorted c(this->begin(), 0);
const int* travA = this->begin();
const int* travB = merge_with.begin();
int tCountA = 0;
int tCountB = 0;
while ((travA + tCountA)!=this->end()&&(travB + tCountB )!=merge_with.end()){
if (travA[tCountA] < travB[tCountB]){
c.insert(travA[tCountA]);
tCountA++;
}
else{
c.insert(travB[tCountB]);
tCountB++;
}
}
while ((travA + tCountA)!=this->end()){
c.insert(travA[tCountA]);
tCountA++;
}
while ((travB + tCountB) != merge_with.end()){
c.insert(travB[tCountB]);
tCountB++;
}
std::cout << "\n";
return c;
}
int_sorted int_sorted::sort(const int* begin, const int* end) {
if (begin == end)return int_sorted(begin, 1);
if (begin == end - 1)return int_sorted(begin, 1);
ptrdiff_t half = (end - begin) / 2;
const int* mid = begin + half;
return sort(begin, mid).merge(sort(mid, end));
}
This is what it looks like when I have int_buffer a(20);
unexpected blank lines

Related

How to implemet copy constructor in C++

this is the header of a class that I have been designing for an assignment. I have included constructors, a destructors, as well as overloaded operators. Could you give me a hint how to properly define the constructors in a class using c++ 20 most recent features in an efficient way.
#ifndef VECTOR_DOUBLE_H
#define VECTOR_DOUBLE_H
#include <memory>
#include <vector>
class vector_double {
public:
vector_double(int size);
vector_double(std::initializer_list<double> lst);
vector_double(const double* array, int size);
vector_double(const vector_doubler& other);
vector_doubleoperator=(const vector_double& other);
// because I use a managed pointer I don't need a destructor
~vector_double() noexcept = default;
void set(int index, double val);
double& get(int index);
const double& get(int index) const;
int size() const;
void reset(double val);
void fill_from(std::initializer_list<double> lst);
void fill_from(const double* array, int size);
int copy_to(std::vector<double>& vec) const;
double& operator[](int index);
const double& operator[](int index) const;
operator double() const;
vector_double add(const vector_double& other) const;
vector_doubleadd(double number) const;
vector_doublemul_by(double number) const;
void resize(int size);
friend std::ostream& operator<<(std::ostream& out, const vector_double& vec);
private:
std::unique_ptr<double[]> m_array;
int m_size;
};
inline std::ostream& operator<<(std::ostream& out, const vector_double& vec){
if (vec.m_size == 0){
out << "{ }";
}
else{
auto first = true;
out << '{';
for (int i=0; i < vec.m_size; ++i){
if (!first)
out << ", ";
else
first = !first;
out << vec.m_array[i];
}
out << '}';
}
return out;
}
#endif //VECTOR_DOUBLE_H
This example definition may help, I tried sticking to C++20 features:
#include <cmath>
#include "vector_double.h"
vector_double::vector_double(int size):
m_array{ new double[size] },
m_size{size}
{}
vector_double::vector_double(std::initializer_list<double> lst): //Constructor that takes an init list
vector_double(lst.size())
{
std::copy(lst.begin(), lst.end(), m_array.get());
}
vector_double::vector_double(const double* array, int size): //Constructor that takes array and size
vector_double(size)
{
// std::copy(array, array + size, m_array.get());
std::copy(&array[0], &array[size], m_array.get());
}
vector_double::vector_double(const vector_double& other): //Copy Constructor
vector_double(other.m_size)
{
std::copy(&other.m_array[0], &other.m_array[m_size], &m_array[0]);
}
vector_double& vector_double::operator=(const vector_double& other) {
if (this != &other) {
if (m_size != other.m_size) {
auto* array = new double[other.m_size];
m_array.reset(array);
m_size = other.m_size;
}
std::copy(&other.m_array[0], &other.m_array[m_size], &m_array[0]);
}
return *this;
}
void vector_double::set(int index, double val) {
if (index < 0 || index > m_size)
throw std::out_of_range("oooh my!");
m_array[index] = val;
}
double& vector_double::get(int index) {
if (index < 0 || index > m_size)
throw std::out_of_range("oooh my!");
return m_array[index];
}
const double& vector_double::get(int index) const {
if (index < 0 || index > m_size)
throw std::out_of_range("oooh my!");
return m_array[index];
}
int vector_double::size() const {
return m_size;
}
void vector_double::reset(double val) {
for (int i=0; i<m_size; ++i){
m_array[i] = val;
}
}
void vector_double::fill_from(std::initializer_list<double> lst) {
int size = std::min((int)lst.size(), m_size);
std::copy(lst.begin(), lst.begin() + size, &m_array[0]);
}
void vector_double::fill_from(const double* array, int size) {
size = std::min(size, m_size);
for (int i = 0; i < size; ++i) {
m_array[i] = array[i];
}
}
int vector_double::copy_to(std::vector<double>& vec) const {
for (int i = 0; i < m_size; ++i) {
vec.push_back(m_array[i]);
}
return m_size;
}
double& vector_double::operator[](int index) {
return m_array[index];
}
const double& vector_double::operator[](int index) const { //Overloading "[]" operator
return m_array[index];
}
vector_double::operator double() const {
double sum = 0.0;
for (int i = 0; i < m_size; ++i) {
sum += m_array[i] * m_array[i];
}
return std::sqrt(sum);
}
vector_double vector_double::add(const vector_double& other) const {
if (m_size != other.m_size)
throw std::logic_error("size mismatch");
auto copy = *this;
for (int i = 0; i < m_size; ++i) {
copy[i] += other[i];
}
return copy;
}
vector_double vector_double::add(double number) const {
auto copy = *this;
for (int i = 0; i < m_size; ++i) {
copy[i] += number;
}
return copy;
}
vector_double vector_double::mul_by(double number) const {
auto copy = *this;
for (int i = 0; i < m_size; ++i) {
copy[i] *= number;
}
return copy;
}
void vector_double::resize(int size) {
if (size != m_size){
auto array = new double[size] {0,};
auto common = std::min(size,m_size);
for (int i = 0; i < common; ++i) {
array[i] = m_array[i];
}
m_array.reset(array);
m_size = size;
}
}

Get error about debug assertion failed: Expression: "(_Ptr_user &(_BIG_ALLOCATION_ALIGNMENT -1)) == 0" && 0

I have a simple example that imitates a vector. I get the debug assertion failed:
C:\program files (x86)\microsoft visual studio 14.0\vc\include\xmemory0 Line: 100
Expression: "(_Ptr_user &(_BIG_ALLOCATION_ALIGNMENT -1)) == 0" && 0
This is my example.
StrVec.h:
#pragma once
#include <string>
#include <memory>
class StrVec
{
public:
StrVec();
StrVec(const StrVec &);
StrVec &operator=(const StrVec &);
~StrVec();
void push_back(const std::string &s);
size_t size() const;
size_t capacity() const;
std::string *begin() const;
std::string *end() const;
private:
void check_volume();
void reallocate();
void free();
std::pair<std::string *, std::string *>
alloc_n_copy(const std::string *, const std::string *);
std::string *elements;
std::string *first_free;
std::string *cap;
static std::allocator<std::string> alloc;
};
StrVec.cpp:
#include "stdafx.h"
#include "StrVec.h"
std::allocator<std::string> StrVec::alloc = std::allocator<std::string>();
StrVec::StrVec()
: elements(nullptr), first_free(nullptr), cap(nullptr) {}
StrVec::StrVec(const StrVec &s) {
auto newBegin = alloc_n_copy(s.begin(), s.end());
elements = newBegin.first;
cap = first_free = newBegin.second;
}
StrVec &StrVec::operator=(const StrVec &rhs) {
auto newBegin = alloc_n_copy(rhs.begin(), rhs.end());
free();
elements = newBegin.first;
cap = first_free = newBegin.second;
return *this;
}
StrVec::~StrVec(){
free();
}
std::pair<std::string *, std::string *>
StrVec::alloc_n_copy(const std::string *b, const std::string *e) {
auto newMem = alloc.allocate(e - b);
return{ newMem, std::uninitialized_copy(b, e, newMem) };
}
void StrVec::reallocate() {
size_t newSize = size() ? 2 * size() : 1;
auto newBegin = alloc.allocate(newSize);
auto newPos = newBegin;
auto oldBegin = elements;
for (size_t i = 0; i < size(); ++i) {
alloc.construct(newPos++, std::move(*oldBegin++));
}
free();
elements = newBegin;
first_free = newPos;
cap = newBegin + newSize;
}
size_t StrVec::size() const {
return first_free - elements;
}
size_t StrVec::capacity() const {
return cap - elements;
}
void StrVec::push_back(const std::string &s) {
check_volume();
alloc.construct(first_free++, s);
}
std::string *StrVec::begin() const {
return elements;
}
std::string *StrVec::end() const {
return first_free;
}
void StrVec::check_volume() {
if (size() == capacity()) reallocate();
}
void StrVec::free() {
if (elements) {
for (auto p = first_free; p != elements; --p) {
alloc.destroy(p);
}
alloc.deallocate(elements, cap - elements);
}
}
main.cpp:
int main()
{
StrVec a;
a.push_back("abc");
StrVec b;
b = a;
return 0;
}
I have stepped through the code. It failed when return at the main function.
I think maybe it's an out-of-range error, but I cannot find the boundary that I have crossed.
Thanks
It should be destroy(—p) instead of destroy(p—). destroy uninitialized memory on destruction lead to the error.

How to fix "Error in `./a.out': corrupted double-linked list:" in C++

My code compiles successfully, but when I try to run it, I keep getting this error: * Error in `./a.out': corrupted double-linked list: 0x00000000021c1280 *
Aborted
This is my VectorDouble.cpp file
#include<bits/stdc++.h>
#include <cstring>
#include "VectorDouble.h"
#include <iostream>
using namespace std;
VectorDouble::VectorDouble() {
cout<<"constructor called"<<endl;
max_count = 50;
arr = new double[this->max_count];
count = 0;
}
VectorDouble::VectorDouble(int max_count_arg) {
max_count = max_count_arg;
arr = new double[max_count_arg];
count = 0;
}
VectorDouble::VectorDouble(const VectorDouble& copy) {
max_count = copy.max_count;
arr = new double[this->max_count];
count = copy.count;
}
VectorDouble::~VectorDouble() {
delete []arr;
}
VectorDouble VectorDouble::operator =(VectorDouble& copy) {
VectorDouble temp(copy.max_count);
for(int i =0; i<=this->count;i++){
temp.arr[i]=copy.arr[i];
}
return temp;
}
bool VectorDouble::operator ==(VectorDouble b) const {
bool isEqual = true;
if(this->count == b.count){
for(int i = 0; i<=this->count; i++){
if(this->arr[i] == b.arr[i]){
isEqual= true;
}
else{
return false;
}
}
}
return isEqual;
}
void VectorDouble::push_back(double num) {
if(this->count+1>this->max_count){
this->max_count *= 2;
VectorDouble temp(2*(this->max_count));
for(int i = 0; i<this->max_count; i++){
temp.arr[i]=this->arr[i+1];
}
temp.arr[count+1] = num;
}
else{
this->arr[count+1]=num;
this->count++;
}
}
int VectorDouble::capacity() {
return this->max_count;
}
int VectorDouble::size() {
return this->count;
}
void VectorDouble::resize(unsigned int size, double defaultVal) {
if(size>(this->count)){
for(int i = this->count; i<size; i++){
this->arr[i] = defaultVal;
}
this->count=size;
}
else{
for(int i = size; i < this->count; i++){
this->arr[i] ='\0';
}
this->count=size;
}
}
void VectorDouble::reserve(unsigned int size) {
if(size>(this->max_count)){
this->max_count = size;
}
}
double VectorDouble::value_at(unsigned int i) {
if(i>(this->count)){
throw std::logic_error("out of bounds");
}
return this->arr[i];
}
void VectorDouble::change_value_at(double newValue, unsigned int i) {
if(i>(this->count)){
throw std::logic_error("out of bounds");
}
this->arr[i]=newValue;
}
ostream& operator<<(ostream& os, const VectorDouble &vd)
{
for(int i = 0; i < vd.count; i++){
os << vd.arr[i] << " ";
}
return os;
}
This is my VectorDouble.h file
#ifndef DYNAMICARRAY_H
#define DYNAMICARRAY_H
#include <iostream>
using namespace std;
class VectorDouble {
public:
int max_count;
int count;
double* arr;
public:
VectorDouble();
VectorDouble(int max_count_arg);
VectorDouble(const VectorDouble& copy);
~VectorDouble();
VectorDouble operator =(VectorDouble& copy);
bool operator ==(VectorDouble b) const;
void push_back(double num);
int capacity();
int size();
void reserve(unsigned int size);
void resize(unsigned size, double defaultVal = 0.0);
double value_at(unsigned int i);
void change_value_at(double newValue, unsigned int i);
friend ostream& operator<<(ostream& os, const VectorDouble &vd);
// DO NOT CHANGE THE FOLLOWING LINE OF CODE. It is for the testing framework
// DO NOT IMPLEMENT THE FOLLOWING FUNCTION. It is implemented by the testing framework
friend int reserved_driver_main();
};
#endif
This is my main.cpp file
#include <iostream>
#include "VectorDouble.h"
using namespace std;
int user_main() {
// test 1, verify that default constructor initializes max_count
VectorDouble v;
if (v.max_count == 50)
{
std::cout << "1.1. default constructor: max_count = 50; test passed" << std::endl;
}
else
{
std::cout << "1.1. default constructor: max_count != 50; test failed" << std::endl;
}
return 0;
}

How to make the operator= in a Vector class?

I don't know, which is not correct, the copy constructor or the operator=. I tested with two "tombs", and the printer is working, but at the end of the program the compiler said "debug assertion failed".
#pragma once
#include <cstdio>
#include <cmath>
#include <iostream>
#include <cstdlib>
class tomb {
private:
double *adat;
int szam;
public:
tomb(){
adat = NULL;
szam = 0;
}
tomb(const tomb &u) {
adat = u.adat;
szam = u.szam;
};
int meret()const {
return szam;
}
~tomb() {
delete[] adat;
}
double & operator[](int n) {
return adat[n];
}
const double & operator[](int n)const {
return adat[n];
}
const tomb &operator=(const tomb &a) {
adat = a.adat;
szam = a.szam;
return *this;
}
tomb elso_valahany(int n) {
}
void push_back(const double &a) {
double *tmp;
tmp = new double[szam+1];
for (int i = 0; i < szam; i++)
{
tmp[i] = adat[i];
}
tmp[szam] = a;
delete[] adat;
adat = tmp;
++szam;
}
void Kiir()const {
for (int i = 0; i < szam; i++)
{
std::cout << adat[i] << "\n";
}
}
};
As per the comments, I'll show you how to do a deep copy: every time you copy the class, you will not be copying just the pointer to the data, but the whole vector instead.
Also, for the sake of simplicity, I'll use std::vector:
#pragma once
#include <cstdio>
#include <cmath>
#include <iostream>
#include <cstdlib>
#include <vector>
class tomb {
private:
std::vector<double> adat;
int szam;
public:
tomb(){
szam = 0;
}
tomb(const tomb &u) : adat(u.adat), szam(u.szam)
{
adat = u.adat;
szam = u.szam;
};
int meret() const {
return szam;
}
~tomb() {
}
double & operator[](int n) const {
return adat[n];
}
const double & operator[](int n) const {
return adat[n];
}
tomb& operator=(const tomb &a) {
adat = a.adat;
szam = a.szam;
return *this;
}
tomb elso_valahany(int n) {
}
void push_back(const double &a) {
adat.push_back(a);
++szam;
}
void Kiir()const {
for (int i = 0; i < szam; i++)
{
std::cout << adat[i] << "\n";
}
}
I haven't compiled/tested, but it should be fine now, as the memory management is done by std copy constructors!

C++, classes, Segmentation fault, all over the programme

I got an exercise form my teacher (the main() function) and was supposed to write functions and classes so that it would work. But I have seg fault and have no idea what to do about it. I would be grateful for any recommendations.
#include <iostream>
class TSeries{
public:
TSeries()
{
_size = 0;
_capacity = 0;
_tab = NULL;
}
TSeries(float *tab, const int size)
{
_tab = new float[size];
for(int i =0;i<size;i++) _tab[i] = tab[i];
_size = size;
}
~TSeries(){delete [] _tab;}
TSeries & operator+=(float value){return insert(value);}
TSeries & operator,(float value){return insert(value);}
TSeries & operator+(const TSeries & s)
{
// if(this->_size != s._size) std::cout<<"Size doesn't match!"<<std::endl;
/*else
{
std::cout<<"whee";
for(int i; i<this->_size;i++)
{
//this->_tab[i] += s._tab[i];
std::cout<<"nothing";
}
return *this;
}*/
std::cout<<"sth";
}
TSeries & operator()(int position1, int position2){}
TSeries & insert(float k)
{
if(_size >= _capacity) Enlarge();
_tab[_size++] = k;
return *this;
}
friend std::ostream & operator<<(std::ostream & out, const TSeries & s);
private:
int _size, _capacity;
float *_tab, *_itr;
static int _nr;
void Enlarge()
{
_capacity = 2 * _capacity + 1;
float *tmp = new float[_capacity];
for( int i=0;i<_size;++i)
{
tmp[i] = _tab[i];
}
delete [] _tab;
_tab = tmp;
}
};
std::ostream & operator<<(std::ostream & out, const TSeries & s)
{
int przedostatni = s._size - 1;
out<<"(";
for(int i =0;i<s._size;i++)
{
out<<(int)s._tab[i];
if(i != przedostatni)
out<<",";
}
out<<")"<<std::endl;
}
using namespace std;
int main(int argc, char **argv) {
TSeries series1;
series1 += 1.,2.,4.,2.;
cout<<"Series1: "<<series1<<endl;
const int size=7;
float tab[size] = {3.,3.,3.,4.,5.,1.,0.};
const TSeries series2(tab,size);
cout<<"Series2: "<<series2<<endl<<endl;
TSeries series3 = series1+series2;
cout<<"Series3: "<<series3<<endl<<endl;
series1+=1.,0.,3.;
series3=series1+series2;
cout<<" "<<series1<<endl;
cout<<" +"<<series2<<endl;
cout<<" ---------------------"<<endl;
cout<<"Series3: "<<series3<<endl<<endl;
//TSeries series4=series1(2,4);
cout<<"Series4: "<<series3<<endl;
return 0;
}
You fixed one of your problems (the assignment to the _tab pointer).
The other problem should have caused a warning from the compiler.
You need to return out from your operator<< method.
Note that you also should use the out parameter, rather than always using cout in the the method.