Note: Similar questions have been asked, but nearly all that I've found seem to make direct use of a pointer which may not be relevant here
For this snippet of code
#include <iostream>
#include <string>
#include <vector>
#include <map>
using namespace std;
class Unit{
public:
string name;
char value;
vector<Unit> inner;
Unit(string Name){
name=Name;
}
Unit(char Value){
name="Character";
}
};
class Instruction{
public:
int size;
string type;
string value;
map<string, vector<Unit>> vars;
vector<Instruction> inner;
vector<Instruction> outer;
Instruction(string Type,string Value,vector<Instruction>& Outer,map<string, vector<Unit>> &Vars){
type=Type;
value=Value;
outer=Outer;
vars=Vars;
size=0;
}
Instruction(string Type,vector<Instruction>& Outer,map<string, vector<Unit>> &Vars){
type=Type;
outer=Outer;
vars=Vars;
size=0;
}
bool matches(vector<Unit> &info,int position=0, int vectLocation=0){
cout<<value<<'\n'; //Segmentation Fault Occurs Here
return false;
}
};
void breakUp(vector<Unit>&u,string s){
for(int i=0;i<s.size();i++){
u.push_back(Unit(s[i]));
}
}
int main(){
//String to be matched
vector<Unit> v;
breakUp(v,"For the love of tests");
//Instruction Vector
vector<Instruction> i;
//Var Vector
map<string, vector<Unit>> x;
//Add initial instruction
Instruction constant("Constant","",i,x);
constant.inner.push_back(Instruction("String","For the love of tests",constant.inner,x));
//Test match
bool result=i[0].matches(v);
if(result==true){
cout<<"Match True\n";
}else{
cout<<"Match False\n";
}
return 0;
}
I get a segmentation fault when attempting to access one of the data members within the matches function. This also occurs when it attempts to print size or type. I have not been able to discern the exact cause of this memory issue and would appriciate any advice or considerations.
vector<Instruction> i;
...
bool result=i[0].matches(v);
i is empty, so accessing i[0] yields undefined behavior.
The reason for SIGSEGV seems to be
bool result=i[0].matches(v);
When you did
vector<Instruction> i;
A new std::vector object was created with size 0.
Now, when you try to access the first element by the above statement, it may give Segmentation fault.
Suggestion:
1) Use const std::string & instead of std::string in the constructor. Using std::string will lead to the string getting copied twice (which won't be good for performance).
Related
I just started learning about vectors, and they seem really handy, if talking about lists from a file. But I'm having a problem while trying to return a new vector from a class method and put it to another method of the same class.
i.e.
#include <iostream>
#include <vector>
#include <fstream>
#include <string>
using namespace std;
class A
{
public:
string name;
string age;
};
class Test
{
string name;
string age;
public:
void get(vector<A> students)
{
vector<A> specificStudents;
//rewrite a couple of students from vector<A>students
//to vector<A> specificStudents
};
void set(vector<A> specificStudents)
{
//I need to get vector<A> specificStudents here
};
};
int main()
{
vector<A> students;
A stud;
ifstream file("file.txt");
for (int i = 0; i < file.eof(); i++)
{
getline(file, stud.name);
getline(file, stud.age);
students.push_back(stud);
};
Test test;
test.get(students);
return 0;
}
Can I return it as a function argument?
It is not entirely clear, but do you want to save a copy of students inside test?:
class Test
{
vector<A> specificStudents;
public:
const vector<A>& get() const
{
return specificStudents;
}
void set(const vector<A>& students)
{
specificStudents = students;
// maybe modify `specificStudents` here in some way or assign it differently
}
};
int main()
{
vector<A> students;
A stud;
ifstream file("file.txt");
while (getline(file, stud.name) && getline(file, stud.age))
{
students.push_back(stud);
}
Test test;
test.set(students);
//... Do something with test
return 0;
}
If you don't know yet what & and const mean in this, you can just remove them (until you learn about them).
You seem to have gotten get and set mixed up. By usual convention, get gets something stored in the class object to the caller and set sets something in the class object (with a value provided by the caller).
I also fixed your input loop. I don't know what you thought file.eof() does, but comparing to i does not do anything useful.
Also be aware of where ; belongs and where it doesn't. It belongs after single statements and class definitions, but not after } of function definitions or other statement blocks, such as the one of while.
YES, you can return vector from a function.
To do this you can write a function like this one:
std::vector<A> get(vector<A> students)
and the inside it return the vector. An example can be:
vector<A> get(vector<A> students)
{
vector<A> specificStudents;
//rewrite a couple of students from vector<A>students
//to vector<A> specificStudents
return specificStudents;
};
I have 2 classes.
First Class - Midgam - The constructor has the following line:
midgam = new Vector[20];
The second class - Vector - where I create an array named array.
The program works great just that I have a little problem.
At the end of the program I try to print in alphabetical order, I use the BubbleSort sorting. The sorting works fine but something in the Swap function stops.
This is how it looks:
void Midgam::Swap(Vector *xp, Vector *yp) {
Vector temp = *xp;
cout << temp.getName() << endl;
*xp = *yp;
*yp = temp;
}
void Midgam::bubbleSort() {
int i, j;
for (i = 0; i < iterator - 1; i++) {
for (j = 0; j < iterator - i - 1; j++) {
if (midgam[j].getName().compare(midgam[j+1].getName()) > 0) {
Swap(&midgam[j], &midgam[j+1]);
}
}
}
}
I work with Visual Studio, the program stops and the program shows me the following code snippet in the Vector class:
Vector::~Vector() {
if (array)
delete[] array;
}
full definitions of Midgam:
#include <iostream>
#include <string>
#include "Vector.h"
using namespace std;
#ifndef MIDGAM_H_
#define MIDGAM_H_
class Midgam {
private:
int boxNum;
int maxParties;
int iterator;
Vector *midgam;
public:
Midgam(int num_of_boxes, int num_of_parties);
virtual ~Midgam();
void Start();
void Menurmal();
void SumOfEzor();
double SumOfParty(string name);
int SumAllVotes();
void AddParty();
void Swap(Vector *xp, Vector *yp);
void bubbleSort();
void Histograma();
void PrintStars(int num);
int FindPartyByName(string party);
void PrintAll();
};
#endif /* MIDGAM_H_ */
full definitions of Vector:
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
#ifndef VECTOR_H_
#define VECTOR_H_
class Vector {
private:
string name;
int size;
unsigned int *array;
bool Bool;
public:
Vector(string name, int size);
Vector();
Vector & operator=(const Vector &);
virtual ~Vector();
bool StringToArray(string str);
bool getBool();
string getName();
unsigned int getAddress();
int getSize();
unsigned int getValueFromArray(int index);
double sumOfArray();
void PrintArray();
};
#endif /* VECTOR_H_ */
Does anyone know why it does not work? Thank you
Your Vector lacks a proper copy constructor.
Vector temp = *xp;
//NOT EQUAL TO:
//Vector temp;
//temp=*xp;
The above statement won't call operator=(const Vector &) even though there's an equal sign. The following line is correct and equivalent:
Vector temp(*xp);
The reason is that this is a copy initialization - temp is created and so a constructor must be called - in particular the copy constructor Vector(const Vector &). Which you did not explicitly declared and so a default one was used.
Then a shallow copy is made, temp and *xp then share the same array and when both their destructors get called the second one will try to delete already deleted memory - undefined behavior which triggers Visual Studio's debugger (at least in debug mode).
The solution is to do a proper deep copy - create a new array and copy its contents:
#include <algorithm> #Contains std::copy_n
Vector::Vector(const Vector& other)
{
name=other.name;
size=other.size;
//Creates a new array
array= new unsigned int[size];
//Copies the array contents
std::copy_n(other.array,size,array);
Boo=other.Bool;
}
Also this is a prime example of why not to use raw memory. I get that you are implementing custom vector and don't want to use std::vector for the array but at least use std::unique_ptr. If you would have just done that you wouldn't have to ask this question in the first place as the compiler would have complained and the debugger wouldn't have to do the compiler's job.
Hi there I keep getting error for the code below which I think makes sense!
I'm trying to use a member of the first struct in a function in the second struct. I code in Xcode and this is the error I get:
No member named 'PLZ' in 'std::__1::vector >'
#include <iostream>
#include <string>
#include <vector>
using namespace std;
struct place {
string PLZ;
string name;
};
struct adresse {
string firstN;
string lastN;
string Str;
string Hsnum;
string PLZ;
void print(vector<place> a){
cout<<a.PLZ;
}
};
int main()
{
return 0;
}
Just define the function at least like
void print(const vector<place> &a) const
{
for ( const auto &place : a )
{
cout << place.PLZ << ' ';
}
}
std::vector is a container that can contain several elements. So you have to specify whether you are going to output all elements of a vector or a concrete element.
The function above outputs the data member PLZ of each element of the vector.
I wrote a class template for an array data structure like so:
#pragma once
#include <cstdlib>
template<typename T, unsigned int N>
class CArray {
public:
CArray();
T& operator [] (unsigned int index);
private:
T *entries;
};
template<typename T, unsigned int N>
CArray<T, N>::CArray()
{
entries = (T *)malloc(N*sizeof(T));
}
template<typename T, unsigned int N>
T& CArray<T, N>::operator [] (unsigned int index) {
if (index >= N) {
throw ;
} else {
return entries[index];
}
}
I wrote a minimal wrapper class that stores string objects, like so:
#pragma once
#include <string>
using namespace std;
class CEntry
{
public:
CEntry();
const string & getSymbol() const;
void setSymbol(string);
protected:
string m_value;
};
Implementation:
#include "CEntry.hpp"
CEntry::CEntry() : m_value(""){
}
const string & CEntry::getSymbol() const {
return m_value;
}
void CEntry::setSymbol(string value) {
m_value = value;
}
When i execute the following main:
#include <iostream>
#include <string>
#include "CEntry.hpp"
#include "CArray.hpp"
int main(int argc, char** argv) {
CArray<CEntry, 2000> test;
test[0].setSymbol("asdf");
cout << test[0].getSymbol();
}
The program crashes with a segmentation fault.
Thread 1 received signal SIGSEGV, Segmentation fault.
0x00007ffad1783f2a in msvcrt!memmove () from C:\WINDOWS\System32\msvcrt.dll
I inspected the program and the crash happens directly in the line of CEntry, where m_value gets assigned to the passed value (in the setSymbol function).
I am using eclipse on windows. I inspected the m_value variable before assignment and it shows suspect values, e.g. 13451671603782742029 for the string length? Could it be that the CEntry object was initialized but not it's member variables?
I've tried researching but cannot figure out whats happening here, thanks in advance.
Your program is crashing because you are accessing unconstructed string objects.
When you use malloc to allocate memory, the memory is uninitialized and the objects you are trying to use have not been constructed. This is Undefined Behavior and, in this case, is causing the crash.
I am stuck on the output member function of the class. I have no idea how to create it and just simply couting it does not seem to work. also any other advice would be great. thanks in advance
here's the code:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class StringSet
{
public:
StringSet(vector<string> str);
void add(string s);
void remove(int i);
void clear();
int length();
void output(ostream& outs);
private:
vector<string> strarr;
};
StringSet::StringSet(vector<string> str)
{
for(int k =0;k<str.size();k++)
{
strarr.push_back(str[k]);
}
}
void StringSet::add(string s)
{
strarr.push_back(s);
}
void StringSet::remove(int i)
{
strarr.erase (strarr.begin()+(i-1));
}
void StringSet::clear()
{
strarr.erase(strarr.begin(),strarr.end());
}
int StringSet::length()
{
return strarr.size();
}
void StringSet::output()
{
}
int main()
{
vector<string> vstr;
string s;
for(int i=0;i<10;i++)
{
cout<<"enter a string: ";
cin>>s;
vstr.push_back(s);
}
StringSet* strset=new StringSet(vstr);
strset.length();
strset.add("hello");
strset.remove(3);
strset.empty();
return 0;
}
Ok, you should begin by solving some errors in your code:
You use a pointer to StringSet and after that you are trying to access the member-functions with the . operator instead of the ->. Anyway, do you really need to allocated your object dynamically ?
StringSet strset(vstr); // No need to allocated dynamically your object
After that, you are calling an empty() method which does not exist...
Also if you stay on dynamic allocation, don't forget to deallocated your memory :
StringSet* strset = new StringSet(vstr);
// ...
delete strset; // <- Important
Finally, I think that your function output should write in the stream the content of your vector, you can do it that way :
#include <algorithm> // For std::copy
#include <iterator> // std::ostream_iterator
void StringSet::output( ostream& outs )
// ^^^^^^^^^^^^^ don't forget the arguments during the definition
{
std::copy(strarr.begin(), strarr.end(), std::ostream_iterator<string>(outs, "\n"));
}
HERE is a live example of your code fixed.
I would suggest you to understan how class works : http://www.cplusplus.com/doc/tutorial/classes/
If your output function is going to print the state of the StringSet object, you may implement is like this:
#include<iterator> //std::ostream_iterator
#include<algorithm> //std::copy
void StringSet::output(ostream& outs)
{
std::copy(starr.begin(), starr.end(), std::ostream_iterator<string>(outs, "\n"));
}