cannot sort a vector of objects that has array in it - class

Hi I am using a class that has an integer and array and creating a vector of the classes objects but I cannot sort it also don't know to store in it.
I am a BEGINNER on c++ so i just wanted to know if I am wrong and how to
do that thing
here n = no of times the program has to execute
num = to store the no. of elements in vector a
but problem loop for(j=0;j<arr[i].a.end();j++)
and also pushback is not working
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
class subcont
{
public:
int num;
vector<int> a;
};
int main()
{
vector<subcont> arr(100);
int i,j,k,l,n,num1,num2;
cin>>n;
for(i=0;i<n;i++)
{
cin>>arr[i].num;
for(j=0;j<arr[i].num;j++)
{
cin>>num2;
cin>>arr[i].a.pushback(num2);
}
}
for(i=0;i<n;i++)
{
sort(arr[i].a.begin(),arr[i].a.end());
}
for(i=0;i<n;i++)
{
cout<<arr[i].num;
for(j=0;j<arr[i].a.end();j++)
cout<<arr[i].a[j];
}
return 0;
}

The problems you describe sound as if you could at least compile your code, which I can't. In fact, the compiler error messages (if one first ignores the large amount of error noise generated by unhappy templates) should hint to most important problems.
Logical problems on first sight: In for(j=0;j<k;j++) the value of k is undefined. In for(j=0;j<arr[i].a.end();a++) the a++ does not make sense.
In cin>>arr[i].a.pushback[num]; the num should probably be num2. Please check your code for more such typoes.
Your sort fails because a is a C array and not a C++ container, so a.begin() and a.end() are not defined.
Stylistic problem: While it makes life a lot easier, mayn people strictly recommend to not use using namespace std;
Additional remark: Why not use std::vector<int> in place of subcont?

Related

Can Sal annotate that parameter members may be mutated?

I am writing a reference-counted linked list of characters data structure in C for practice. I want to try using Sal in it to annotate function parameters for this practice.
I have an input paremeter(named This), which I want to annotate to make it clear that the specified parameter's members must be mutable in order for the function to behave as expected.
The situation is analogous to the code below.
#include <Windows.h>
typedef struct Box {
ULONG val;
} Box;
ULONG Box_decrement(_In_ Box *This) {
return InterlockedDecrement(&(This->val));
}
int main(int argc, char **argv) {
Box b = {2};
Box_decrement(&b);
return (BYTE)b.val;
};
Is there an existing Sal annotation that can be used to annotate the This parameter of the Box_increment function to make it clear from the function signature that the function modifies one or more members of the Box that has been passed to it?
Something like _InternallyMutable_(but exist):
#include <Windows.h>
typedef struct Box {
ULONG val;
} Box;
ULONG Box_decrement(_InternallyMutable_ _In_ Box *This) {
return InterlockedDecrement(&(This->val));
}
int main(int argc, char **argv) {
Box b = {2};
Box_decrement(&b);
return (BYTE)b.val;
};
Best solution so far(unfortunately, there does not seem to be any equivelent in SAL to denote Internally_mutable, there is Unchanged which is the opposite):
#include <Windows.h>
#define _Internally_mutable_(expr) _At_(expr, _Out_range_(!=, _Old_(expr)))
typedef struct Box {
ULONG val;
} Box;
ULONG Box_decrement(_In_ _InternallyMutable_(This) Box *This) {
return InterlockedDecrement(&(This->val));
}
int main(int argc, char **argv) {
Box b = {2};
Box_decrement(&b);
return (BYTE)b.val;
};
Yes! You can. SAL is a wonderful DSL that lets you do basically anything you want if you're psychic enough to infer it from the little bits in the Windows SDK. I've even in the past been able to write super simple custom annotations to detect invalid HANDLE usage with _Post_satisfies_ and friends.
This code seems to work:
_At_(value, _Out_range_(!=, _Old_(value)))
void change_value_supposed_to(int& value) noexcept {
//value += 1;
}
...Running with all native rules in code analysis, I get a warning like this:
Warning C28196 The requirement that '_Param_(1)!=(("pre"), _Param_(1))' is not satisfied. (The expression does not evaluate to true.)
(there, substitute value with your variable)
For _Internally_mutable_, I can do it in the "above the function" style of SAL:
#define _Internally_mutable_(expr) _At_(expr, _Out_range_(!=, _Old_(expr)))
_Internally_mutable_(value)
void change_value_supposed_to_internally_mutable(int& value) noexcept {
//value += 1;
(void)value;
}
...but not inline WITHOUT being repetitive, as you wanted. Not sure why right now - _Curr_ doesn't seem to be working? - I may need another layer of indirection or something. Here's what it looks like:
#define _Internally_mutable_inline_(value) _Out_range_(!=, _Old_(value))
void change_value_supposed_to_internally_mutable_inline(_Internally_mutable_inline_(value) int& value) noexcept {
//value += 1;
(void)value;
}
How I figured this out:
sal.h defines an _Unchanged_ annotation (despite doing web dev for several years now and little C++, I remembered this when I saw your question in a google alert for SAL!):
// annotation to express that a value (usually a field of a mutable class)
// is not changed by a function call
#define _Unchanged_(e) _SAL2_Source_(_Unchanged_, (e), _At_(e, _Post_equal_to_(_Old_(e)) _Const_))
...if you look at this macro closely, you'll see that it just substitutes as:
_At_(e, _Post_equal_to_(_Old_(e)) _Const_)
...and further unrolling it, you'll see _Post_equal_to_ is:
#define _Post_equal_to_(expr) _SAL2_Source_(_Post_equal_to_, (expr), _Out_range_(==, expr))
Do you see it? All it's doing is saying the _Out_range_ is equal to the expression you specify. _Out_range_ (and all the other range SAL macros) appear to accept all of the standard C operators. That behavior is not documented, but years of reading through the Windows SDK headers shows me it's intentional! Here, all we need to do is use the not equals operator with the _Old_ intrinsic, and the analyzer's solver should be able to figure it out!
_Unchanged_ itself is broken?
To my great confusion, _Unchanged_ itself seems broken:
_Unchanged_(value)
void change_value_not_supposed_to(_Inout_ int& value) noexcept {
value += 1;
}
...that produces NO warning. Without the _Inout_, code analysis is convinced that value is uninitialized on function entry. This makes no sense of course, and I'm calling this directly from main in the same file. Twiddling with inlining or link time code generation doesn't seem to help
I've played a lot with it, and various combinations of _Inout_, even _Post_satisfies_. I should file a bug, but I'm already distracted here, I'm supposed to be doing something else right now :)
Link back here if anybody does file a bug. I don't even know what the MSVC/Compiler teams use for bug reporting these days.
Fun facts
5-6 years ago I tried to convince Microsoft to open source the SAL patents! It would have been great, I would have implemented them in Clang, so we'd all be able to use it across platforms! I might have even kicked off a career in static-analysis with it. But alas, they didn't want to do it in the end. Open sourcing them would have meant they might have to support it and/or any extensions the community might have introduced, and I kinda understand why they didn't want that. It's a shame, I love SAL, and so do many others!

pointers to vectors as class members pointers to vectors in functions

I'm a noob. Using C++ in Clion
I'm building a graph of N random nodes on a Cartesian plane
I have a simple type, node (just a point) (int x, int y)
node pt(x,y)
I have a vector of N randomly generated unique points (would this be considered ordered points btw?)
vector NodeList(N);
I have a class Graph (Incomplete) which has a function GenNodelist which I have tested as a standalone program. I had a hell of a time just getting the constructor to build without compile error.
#include <iostream>
#include <vector>
#ifndef DIJKSTRA_GRAPH_H
#define DIJKSTRA_GRAPH_H
using namespace std;
class Graph {
private:
int x;
int y;
vector<int> NodeList;
int *np;
public:
//constructor
x(x),y(y),NodeList(),np(){}
void GenNodeList(vector<int> NL(), int &np) {x,y,NodeList, &np; }
void GenNodeList(vector<int> *NL, int *p);
};
#endif //DIJKSTRA_GRAPH_H
void Graph::GenNodeList(vector<int>* NL, int* p) {
.
.
} .
... code that builds and has been quasi tested
So everything builds and there's a "hello world" main program in the project. The 2 classes, (node & Graph: 2 headers and 2 cpp files) along with the main "hello world" build and run. Now from main() I wan to call the call the GenNode function from main. I just want to pass a pointer and have the list generate and sit in memory UN-mutable. right now. I'll build the graph off of this later. When I try to call the function nothing works. How can I build this list and access it from main() and Graph()?
main(){
vector<int> NL(N);
int *np;
Graph::GenNodeList( NL, np);
}
Can't seem to figure this out.
This incomplete piece of code
Graph::GenNodeList( NL, np);
is ill-formed because that method is not static. You have to access instance of class Graph for non-static members. Nothing about oop here, just language's rules.
Graph(): x(x),y(y),NodeList(),np(){}
static void GenNodeList(vector<node>* NL, node* np);
void Graph::GenNodeList(vector<node>* NL, node* p) {
int main() {
vector<node> NL(N);
vector<node>* NList;
node *np = nullptr;
NList = &NL;
Graph::GenNodeList(NList,np);
return 0;
https://github.com/Pasqualino31/Dijkstra/tree/Pasqualino31-patch-2

Creating a class to throw in case of error

I have created my own vector class that behaves somewhat like the usual std::vector (I needed to do this for this assignment). Now I want to make sure that if someone tries to write something into this vector class that is out of range of the memory it has access to, it gives an error and terminates the program.
My attempt:
template<typename T>
class vector
{
private:
T *elements;
int sz;
public:
// vector functions etc. //
struct out_of_range
{
string s;
out_of_range(string b) : s{b} {cerr << "error: " << s << endl;}
};
};
So now in my vector member functions that can run into an out of range error, i throw this class. For example in my operator overloading of [], I have a check like this:
if(i < 0 || sz <= i) throw out_of_range("index out of range");
Now this works, and terminates the program with the following message:
error: index is out of range
terminate called after throwing an instance of 'vector::out_of_range'
Aborted (core dumped)
My question is if this is the correct approach. Am I allowed to cerr from a function like I have and can I simply throw this function without catching it? As far as I'm aware, throwing without catching calls terminate() right? Is this bad coding practice?
I hope I haven't confused you guys and that my question is somewhat understandable. Thanks for any help in advance :)
edit: sorry I should have mentioned, I am not permitted to use any classes I have not created myself except for some basic ones like std::string and the basic inputs and outputs.
Different of Java, in C++ you could use non-exception-specific elements to use in a throw statement. So, your struct is suitable to be used as expression parameter for throw an exception such that (just like an int number does).
However, since you are using an OOP approach to write your programs, you should also apply a class alternative for your exceptions:
#include <iostream>
#include <exception>
using namespace std;
class myexception: public exception {
virtual const char* what() const throw() {
return "My exception happened";
}
} myex;
int main () {
try {
throw myex;
} catch (exception& e) {
cout << e.what() << '\n';
}
return 0;
}
Taken from here.
The first impression is that the both alternatives are equivalent. The benefit of the class based over the struct based is that with a class you can extract the benefits of reuse, extension, encapsulation and so on provided by the object oriented approach which can be valuable when programming more complex, huge and long life systems.

The rule of The Big Three

Iam confused with the below question I did the program as per my understanding but it crashes what am I doing wrong? If someone can please assist me it would be much appreciated.
my main.cpp looks like this:
#include <iostream>
#include <iomanip>
#include "Number.h"
using namespace std;
int main()
{
Number n1(10);
Number n2 = n1;
n2.printNum();
n2.addOne();
n1 = n2;
n1.printNum();
return 0;
}
Then my header file looks like this:
#include <iostream>
using namespace std;
class Number
{
int *p;
public:
Number(int);
void addOne();
void printNum();
};
And the below parts for the constructor I need to complete there where it shows comments that's the part I should complete:
#include <iostream>
#include "Number.h"
using namespace std;
Number::Number(int a1)
{
*p = a1;//write the code needed to initialise the value of the member variable with a1
}
void Number::printNum()
{
cout << "The number is " << *p << endl;
}
void Number::addOne()
{
*p++;//write the code needed to increment the value of the member variable by one.
}
Then the question asks the below what should I do to the code to use the BIG THREE?
Consider the following program. Complete the class definition (where you are asked to) and check the output. You can see that that program works without error once it is completed. However, experts suggest that in any class that uses pointers and the new operator it is better to follow the rule of The Big Three. Modify the class definition to follow the rule of The Big Three and submit the new program and the output. Demonstrate the use of this pointer.
Thank you
Rohan

std::vector in MyClass ptr causing crash on destructor

I have a problem in regards to a custom class I have made. The original intention was to create a particle emitter and in this emitter are two vectors to hold colors and the particles themselves.
The problem exactly is trying to destruct this custom class which functions perfectly if you do not call the destructor, which is obviously bad.
I have reduced this to a very short, compileable example.
Test.h
#include <vector>
class Test{
public:
Test();
~Test();
protected:
std::vector<int> Ints;
};
And the main.cpp:
#include "Test.h"
int main(int argc, char **argv){
Test* t;
delete[] t;
return 0;
}
In the Implementation file is just empty constructor and destructors.
Something to note is, this only happens when the "Test" is a pointer, which would preferred to be avoided.
Will provide more information if needed. Thanks in advance.
You are deleting something that hasn't allocated a memory and that too in wrong way.
Allocate memory first
Test *t = new Test;
then,
delete t; // Note no []
Also, since C++11 is tagged, prefer using smart pointers, which do the memory management for you on its own
If t is a pointer then you need to give it something to point to first, as #P0W points out. But why not just declare t to be a local (stack) variable?
#include "Test.h"
int main(int argc, char **argv){
Test t;
return 0;
}
You are not creating object Test. You have created an pointer of type Test. For a pointer you need to use the keyword "new".
Test * t = new Test();