Coding this in CodeBlocks, this program keeps getting a seg fault. Could anyone help?
#include <string>
#include <iostream>
#include <sstream>
#include "include/hugeint.h"
using namespace std;
int main(int argc, char *argv[])
{
HugeInt h("123");
return 0;
}
my HugeInt Class (whats relevant), stores very large integers as an array of integers
class HugeInt
{
public:
HugeInt(string);
private:
DynArray dyn;
//HugeInt& reverse();
int size;
};
HugeInt::HugeInt(string input)
{
string digits = input;
for(unsigned int i = 0; i < digits.length(); i++){
dyn.add(digits.at(i) - 48);
}
size = dyn.size();
}
my dynamic array class of integers
class DynArray
{
public:
DynArray();
~DynArray();
private:
int length;
int *arr; //points to this array
int nextIndex;
};
DynArray::DynArray() {
arr = new int[10];
for (int i = 0; i < 10; i++)
arr[i] = 0;
length = 10;
nextIndex = 0; }
DynArray::~DynArray()
{
delete [] arr;
}
int DynArray::size(){
return nextIndex;
}
void DynArray::add(int val) {
int *newArr;
if (nextIndex == length) {
length = length + 10;
newArr = new int[length];
for (int i = 0; i < nextIndex; i++)
newArr[i] = arr[i];
for (int j = nextIndex; j < length; j++)
newArr[j] = 0;
delete [] arr;
arr = newArr;
}
arr[nextIndex++] = val;
}
Edit: I commented delete [] arr; out and it still seg faults :/
Edit2: OK so the code works if main is as follows. Can Anyone explain why please?
#include <string>
#include <iostream>
#include <sstream>
#include "include/hugeint.h"
using namespace std;
int main(int argc, char *argv[])
{
string in = "1234";
HugeInt h(in);
return 0;
}
You may need to initialize the DynArray in the HugeInt constructor before you start using the DynArray add() method. You didn't include the add method in the code but if it does what I imagine it does, you may have not constructed the DynArray object before using it, thus the seg fault.
The code you've posted compiles and runs without error.
I can speculate that problems are happening elsewhere because DynArray does not satisfy the rule of three.
Currently, if a DynArray is copied in any way, that copy will hold the same pointer to the same int *arr.
And when that copy is destroyed, so is the array used by all the other copies.
Related
Can anyone please explain why the loop only execute once!!
The for loop executes once and never reaches end of the programm
and if you've got some time to review my mistakes then please point out mistakes because i know this is not how it is done!!
using namespace std;
#include<iostream>
int* rotate(int* ar,int d,int n)
{
int tmp[n];
d = d%n;
for (int i = 0; i < n; ++i)
{
tmp[i] = ar[(i+d)%n];
}
free(ar);
return tmp;
}
int main(int argc, char const *argv[])
{
int arr[] = {1,2,3,4,5};
int *a;
int n = sizeof(arr)/sizeof(arr[0]);
a = rotate(arr,4,n);
cout<<endl;
for (int i = 0; i < n; ++i)
{
cout<<i<<endl;
cout<<a[i]<<endl;
}
cout<<"End";
return 0;
}
Lets take it apart...
int* rotate(int* ar,int d,int n)
{
int tmp[n]; // 1
d = d%n;
for (int i = 0; i < n; ++i)
{
tmp[i] = ar[(i+d)%n];
}
free(ar); // 2
return tmp; // 3
}
int tmp[n]; is not standard C++. If you do not want to use std::vector the proper replacement would be a dynamically allocated array.
You call free with a pointer that was not allocated via malloc, which invokes undefined behavior. In C++ you shouldn't be using free and malloc at all, but rather new and delete. And also new and delete only for such exercise. Otherwise use smart pointers.
You return a pointer to a local variable. The pointer is dangling and using it in main invokes undefined behavior.
You can't simply replace the static array arr in main with something else in the function. A function called rotate is not expected to create a new array or delete the one that was passed (also because like in your case it is just not possible).
There are different ways to fix your code. I choose to make rotate rotate the array "in-place". However, as you can see, the implementation actually uses an additional array of same size. I leave it to you to figure out how to change it to use less additional memory:
#include <iostream>
using std::cout;
using std::endl;
void rotate(int* ar,int d,int n)
{
int* tmp = new int[n];
d = d%n;
for (int i = 0; i < n; ++i)
{
tmp[i] = ar[(i+d)%n];
}
for (int i = 0; i < n; ++i)
{
ar[i] = tmp[i];
}
}
int main(int argc, char const *argv[])
{
int arr[] = {1,2,3,4,5};
int n = sizeof(arr)/sizeof(arr[0]);
rotate(arr,4,n);
cout<<endl;
for (int i = 0; i < n; ++i)
{
cout<<i<<endl;
cout<<arr[i]<<endl;
}
cout<<"End";
return 0;
}
This is how you can do the same using std::rotate:
#include <array>
#include <iostream>
#include <algorithm>
int main(int argc, char const *argv[])
{
int arr[] = {1,2,3,4,5};
int n = sizeof(arr)/sizeof(arr[0]);
std::rotate(std::begin(arr),std::begin(arr)+4,std::end(arr));
for (int i = 0; i < n; ++i)
{
std::cout << i << std::endl;
std::cout << arr[i] << std::endl;
}
std::cout<<"End";
}
... it even uses pointers ;)
I have created a class called DNA, having a no argument constructor and two member functions namely initialize() and show(). The problem is when I create an
array using new operator and call the initialize function on every object using a for loop, instead of getting different string in the member variable "genes", I am getting the exactly the same set of characters (array) in the genes in every object in the array. Although I seed the srand() function before initialization of the string, there is no effect seen of it.
The code below.
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <string>
using namespace std;
string sampleSpace("ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz");
class DNA {
private:
int length;
char *genes;
public:
DNA() {
length = 0;
genes = new char[length];
}
void initialize(int len) {
srand(unsigned(time(NULL)));
this -> length = len;
delete genes;
this -> genes = new char[length];
for (int i = 0; i < length; i++) {
*(genes + i) = sampleSpace.at(rand() % sampleSpace.length());
}
}
void show() {
for (int i = 0; i < length; i++) {
cout<<*(genes + i);
}
cout<<endl;
}
};
int main() {
DNA *dna = new DNA[10];
DNA *temp = dna;
for (int i = 0; i < 10; i++) {
(*temp).initialize(10);
temp++;
}
temp = dna;
for (int i = 0; i < 10; i++) {
(*temp).show();
temp++;
}
return 0;
}
You should use the new random API and use a proper random engine:
class DNA {
private:
int length;
std::unique_ptr<char[]> genes;
static std::default_random_engine random;
public:
DNA() : length{0}, genes{} {}
void initialize(int len) {
this-> length = len;
this-> genes = std::make_unique<char[]>(length);
std::uniform_int_distribution<std::size_t> distribution{0, sampleSpace.size() - 1};
for (int i = 0; i < length; i++) {
genes[i] = sampleSpace.at(distribution(random));
}
}
void show() {
for (int i = 0; i < length; i++) {
cout<<genes[i];
}
cout<<endl;
}
};
This will initialize a std::default_random_engine and use a proper number distribution. Also, I changed the code for unique pointer.
Here's a live example.
To piggyback on the answer given, here is the equivalent answer, but using std::vector and std::generate:
#include <iostream>
#include <algorithm>
#include <ctime>
#include <string>
#include <vector>
#include <random>
std::string sampleSpace("ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz");
class DNA
{
private:
std::vector<char> genes;
public:
void initialize(int len)
{
static std::default_random_engine random;
genes.resize(len);
std::uniform_int_distribution<size_t> distribution{0, sampleSpace.length()-1};
sampleSpace.at(distribution(random));
std::generate(genes.begin(), genes.end(), [&] ()
{ return sampleSpace.at(distribution(random)); });
}
void show()
{
for (auto& v : genes)
std::cout << v;
std::cout << "\n";
}
};
int main()
{
DNA dna[10];
for (int i = 0; i < 10; i++)
dna[i].initialize(10);
for (int i = 0; i < 10; i++)
dna[i].show();
}
Live Example
Note that length is also no longer needed.
I have a class which has overloaded the array index operator[]. Now I have to create a pointer to that class, How can I use index operator [] using pointer to the class. Following code works fine, but if i un-comment the basicVector * a = new basicVector(10) line and put -> in place of ., I get errors.
Please see this link for compiler settings and code.
#include <iostream> // std::cout
#include <queue> // std::queue
#include <string>
#include <string.h>
#include <stdint.h>
#include <vector>
using namespace std;
class basicVector
{
private:
uint32_t array_size;
uint8_t * array;
public:
basicVector(uint32_t n);
~basicVector();
uint32_t size();
uint8_t * front();
uint8_t& operator[](uint32_t i);
};
basicVector::basicVector(uint32_t n)
{
array_size = n;
array = new uint8_t[n];
}
basicVector::~basicVector()
{
delete [] array;
}
uint32_t basicVector::size()
{
return array_size;
}
uint8_t * basicVector::front()
{
return array;
}
uint8_t& basicVector::operator[](uint32_t i)
{
return array[i];
}
int main ()
{ //basicVector * a = new basicVector(10);
basicVector a(10);
cout <<a.size()<<endl;
for(uint8_t i=0; i < a.size(); i++)
{ a[i] = i+50; //how to do this correctly when "a" is pointer?
}
uint8_t * b = &a[3]; //how to do this correctly when "a" is pointer?
*b = 45;
for(uint32_t i=0; i < a.size(); i++)
{ cout<<a[i]<<endl; //how to do this correctly when "a" is pointer?
}
return 0;
}
With the following declaration:
basicVector *a = new basicVector(10);
You could dereference the pointer (preferred):
uint8_t n = (*a)[5];
Or call the operator using the operator syntax:
uint8_t n = a->operator[](5);
#include<iostream>
#include<string>
using namespace std;
char *fun(const char* a)
{
int size=strlen(a);
char* str=new char[12];
for(int i=0;i<size-1;i++)
{
str[i]=a[size-i-1];
}
str[size-1]='\0';
return str;
}
main()
{
int i=0;
char a[11]={'a','y','u','s','h','r','i','k','h','r','a'};
char *p=new char[11];
p=fun(a);
for(int i=0;i<11;i++)
{
cout<<p[i]<<" ";
}
delete(ptr);
}
//having some troubles using array p in the main here please help.
There are many issues:
Here the a array is not NUL terminated, therefore strlen cannot be used on it in fun:
char a[11]={'a','y','u','s','h','r','i','k','h','r','a'};
Here you are allocating a fixed size of 12, but you need a dynamic size depending on the length of the string:
char* str=new char[12];
Then:
str[size-1]='\0';
should be:
str[size] = '\0';
otherwise your resulting string will miss the last character.
In main:
char *p=new char[11];
is pointless because you assign p right after with p=fun(a);.
You call delete(ptr);, but there is no ptr.
And finally you should also #include <string.h> be sure that strlen is defined, but one some platforms it compiles also without #include <string.h>.
You probably want this:
#include <iostream>
#include <string>
#include <string.h>
using namespace std;
char *fun(const char* a)
{
int size = strlen(a);
char* str = new char[size + 1];
for (int i = 0; i < size; i++)
{
str[i] = a[size - i - 1];
}
str[size] = '\0';
return str;
}
int main()
{
char a[] = "ABCDE";
char *p = fun(a);
int size = strlen(p);
for (int i = 0; i < size; i++)
{
cout << p[i] << " ";
}
delete[] p;
}
I tried to write a program but I get segmentation fault (core dumped) while running . When I put a defined array like array_2d[10][1] , the problem is solved but I need to do the memory allocation for my project. It is a simple version of my code:
#include <iostream>
#include <cmath>
#include <fstream>
#include <cstdlib>
#include <string>
using namespace std;
class Exam
{
private:
double** array_2d;
unsigned int num;
unsigned int num1;
public:
Exam();
void memoryallocation();
void show();
};
Exam::Exam()
{
num=10;
num1=1;
}
void Exam::memoryallocation ()
{
double** array_2d = new double*[num];
for (unsigned int i = 0; i < num ;i++)
{
array_2d[i] = new double[num1];
}
}
void Exam::show ()
{
ifstream file;
file.open("fish.txt");
for (unsigned int i = 0; i < num; i++)
{
for (unsigned int j = 0; j < num1; j++)
{
file >> array_2d[i][j];
cout<<array_2d[i][j]<<" ";
}
cout<<endl;
}
file.close();
}
int main()
{
Exam E;
E.memoryallocation();
E.show();
return 0;
}
Inside the function Exam::memoryallocation (), you are declaring array_2d again.
void Exam::memoryallocation ()
{
array_2d = new double*[num]; //remove the redeclaration of array_2d
for (unsigned int i = 0; i < num ;i++)
{
array_2d[i] = new double[num1];
}
}