C++ Linked List Deep Copy Constructor and Assignment Overloaded - constructor

#ifndef LIST
#define LIST
#include <iostream>
#include <cstdlib>
#include <string>
using namespace std;
typedef string ElementType;
class List
{
private:
class Node
{
public:
ElementType data;
Node * next;
Node()
:data(ElementType()), next(NULL)
{}
Node(ElementType initData)
:data(initData), next(NULL)
{}
}; // end of Node class
typedef Node * NodePointer;
public:
private:
NodePointer first;
int mySize;
}; // end of List class
This is my overloaded assignment operator, im not sure what im doing wrong, but im beyond frustrated,I've searched the web and read different forums and cannot find a solution to do this, could someone please push me in the right direction, I left out all my public member functions, because none of them operate on my overloaded assignment and copy constructor, I just wanted you guys to get an idea of my layout
overloaded assignment operator
List & List::operator=(const List &rightSide)
{
if(this != &rightSide)
{
this->~List();
}
NodePointer ptr = rightSide.first;
NodePointer cptr = ptr;
while(ptr != NULL)
{
cptr->next = new Node(ptr->data);
cptr = cptr->next;
ptr = ptr->next;
}
return *this;
}
this is my copy constructor
List::List(const List &source)
{
NodePointer ptr = source.first;
NodePointer cptr;
if(ptr == NULL)
{
cerr << "Bad allocation, empty list" << endl;
exit(1);
}
while(ptr != NULL)
{
cptr = new Node(ptr->data);
cptr->next = ptr->next;
ptr = ptr->next;
}
}

Related

How can I get my queue in C++ work? Unhandeled Exception: Access violation reading location

I got a problem by implementing a queue in C++. I looked for similar problems, but didn't find anything usefull.
I'm using Visual Studio 2019.
I seperated my program in a Main.cpp, a Queue.h and Queue.cpp, Patient.h and Patient.cpp.
I tried to convert the concept for this from Java to C++, but I just can't find a solution for my function getInfo().
I get an exception like this:
Unhandled exception at 0x7C0EF3BE (ucrtbased.dll) in Queue.exe: 0xC0000005: Access violation reading location 0xE8884D8D.
Would be nice if anyone could help me with my problem and explain what I did wrong.
I'm just a beginner so don't be too harsh on me pls xD
Main.cpp:
#include "Queue.h"
#include "Patient.h"
int main() {
Queue queue;
Patient patient1("Name1");
Patient patient2("Name2");
queue.add(patient1);
queue.add(patient2);
queue.getInfo();
}
Queue.h:
#pragma once
#include <iostream>
#include "Patient.h"
using namespace std;
class Queue {
private:
Patient* beginning;
Patient* end;
int amount;
public:
Queue();
void add(Patient p);
Patient remove();
void getInfo();
};
Queue.cpp:
#include "Queue.h"
Queue::Queue() {
beginning = 0;
end = 0;
amount = 0;
}
void Queue::add(Patient p) {
if (amount == 0) {
beginning = &p;
end = &p;
} else {
end->setFollower(p);
end = &p;
}
amount++;
}
Patient Queue::remove() {
if (amount == 0) {
cout << "You can't remove a patient. The Queue is empty!" << endl;
} else {
*beginning = beginning->getFollower();
amount--;
}
return *beginning;
}
void Queue::getInfo() {
if (amount == 0) {
cout << "The Queue is empty!" << endl;
} else {
cout << "There are " << amount << " Patients in the Queue!" << endl;
cout << "The following list provides all Patients in the Queue-order:" << endl;
beginning->getInfo();
}
}
Patient.h:
#pragma once
#include <iostream>
#include <string>
using namespace std;
class Patient {
private:
string name;
Patient* follower;
string* nameptr;
public:
Patient(string newname);
void setFollower(Patient p);
Patient getFollower();
void getInfo();
};
Patient.cpp:
#include "Patient.h"
Patient::Patient(string newname) {
name = newname;
follower = 0;
nameptr = &name;
}
void Patient::setFollower(Patient p) {
follower = &p;
}
Patient Patient::getFollower() {
return *follower;
}
void Patient::getInfo() {
cout << *nameptr << endl;
if (follower == 0) {
cout << "No follower existing!" << endl;
}
else {
follower->getInfo();
}
cin.get();
}
There are a few places where you mix up passing by value with passing by reference.
To start with, the first problem is here:
void Queue::add(Patient p) {
if (amount == 0) {
beginning = &p;
end = &p;
} else {
end->setFollower(p);
end = &p;
}
amount++;
}
You are passing the value of Patient p rather than a reference to the actual object. To fix this you only need to add an "&" to your functional call like this:
void Queue::add(Patient& p) {
if (amount == 0) {
beginning = &p;
end = &p;
} else {
end->setFollower(p);
end = &p;
}
amount++;
}
Note the "&" in the parameters list. Then you must also update the function header:
class Queue {
private:
Patient* beginning;
Patient* end;
int amount;
public:
Queue();
void add(Patient& p);
Patient remove();
void getInfo();
};
You must also pass by reference for your setFollower function:
void Patient::setFollower(Patient& p) {
follower = &p;
}
and in the header file:
void setFollower(Patient& p);
What you need to know going forward is that in C++ all arguments are passed by value unless you specify passing by reference in the function's parameter list. Here is an article about passing variables to functions if you'd like to read more (https://iq.opengenus.org/call-by-value-vs-call-by-reference-cpp/).

C++11 Specialize one version of variadic function

I'm trying to create a variadic function that takes any amount of arguments, but I'd like to specialize the case where only two arguments with iterators are passed in. Passing in two arguments of non-iterators, should still use the generic variadic version. I'm hitting a static_assert failure that I haven't been able to overcome. It seems like it's trying to evaluate the entire expression in with_iterator_args, which fails if the function has less than two arguments, rather than skipping the evaluation of the remainder when the check for 2 arguments already yielded false.
Is there a way to do this without adding two more overloads for the one and two argument case?
This is what I have so far:
#include <iostream>
#include <vector>
#include <tuple>
// inspired by https://stackoverflow.com/a/7943765/2129246
template <typename... Args>
struct args_traits
{
enum { arity = sizeof...(Args) };
template <size_t i>
struct arg
{
typedef typename std::tuple_element<i, std::tuple<Args...>>::type type;
};
};
// based on: https://stackoverflow.com/a/30766365/2129246
template <typename T>
struct is_iterator
{
static char test(...);
template <typename U,
typename=typename std::iterator_traits<U>::difference_type,
typename=typename std::iterator_traits<U>::pointer,
typename=typename std::iterator_traits<U>::reference,
typename=typename std::iterator_traits<U>::value_type,
typename=typename std::iterator_traits<U>::iterator_category
> static long test(U&&);
constexpr static bool value = std::is_same<decltype(test(std::declval<T>())),long>::value;
};
template<typename Arg1, typename Arg2>
struct is_iterator_args
{
constexpr static bool value = is_iterator<Arg1>::value && is_iterator<Arg2>::value;
};
template<typename... Args>
struct with_iterator_args
{
constexpr static bool value = args_traits<Args...>::arity == 2
&& is_iterator_args<typename args_traits<Args...>::template arg<0>::type, typename args_traits<Args...>::template arg<1>::type>::value;
};
template <typename T, typename... Args,
typename = typename std::enable_if<!with_iterator_args<Args...>::value>::type>
void some_func(T first, Args&&... args)
{
std::cout << "func(" << first << ") called with " << sizeof...(args) << " args" << std::endl;
}
template <typename T, typename Begin, typename End,
typename = typename std::enable_if<is_iterator_args<Begin, End>::value>::type>
void some_func(T first, Begin begin, End end)
{
std::cout << "func(" << first << ") called with iterators: " << std::distance(begin, end) << std::endl;
}
int main()
{
std::vector<int> v{1, 2, 3};
some_func(1, v.begin(), v.end()); // special case, using iterators
some_func(1, "arg2", 3, std::string("arg4"));
some_func(1, "arg2");
some_func(1);
some_func(1, "arg2", 3, std::string("arg4"), 5.67);
return 0;
}
This is what fails:
In file included from test.cpp:3:
/usr/include/c++/9/tuple: In instantiation of ‘struct std::tuple_element<0, std::tuple<> >’:
/usr/include/c++/9/tuple:1285:12: required from ‘struct std::tuple_element<1, std::tuple<const char (&)[5]> >’
test.cpp:14:69: required from ‘struct args_traits<const char (&)[5]>::arg<1>’
test.cpp:45:3: required from ‘constexpr const bool with_iterator_args<const char (&)[5]>::value’
test.cpp:49:37: required by substitution of ‘template<class T, class ... Args, class> void some_func(T, Args&& ...) [with T = int; Args = {const char (&)[5]}; <template-parameter-1-3> = <missing>]’
test.cpp:68:21: required from here
/usr/include/c++/9/tuple:1303:25: error: static assertion failed: tuple index is in range
1303 | static_assert(__i < tuple_size<tuple<>>::value,
| ~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~
The problem in your case is that both expression before and after && must compile - even if the expression after the && will not be used.
My first try was to leverage C++17 constexpr if.
template<typename... Args>
struct with_iterator_args
{
private:
constexpr static bool value_checker() {
if constexpr (args_traits<Args...>::arity == 2) {
return is_iterator_args<typename args_traits<Args...>::template arg<0>::type, typename args_traits<Args...>::template arg<1>::type>::value;
}
else {
return false;
}
}
public:
constexpr static bool value = value_checker();
};
If you need to stick with C++11, you could use std::conditional. Please note that I also use std::false_type and std::true_type.
template<typename... Args>
struct is_iterator_args :
std::conditional<is_iterator<typename args_traits<Args...>::template arg<0>::type>::value &&
is_iterator<typename args_traits<Args...>::template arg<1>::type>::value,
std::true_type, std::false_type>::type
{
};
template<typename... Args>
struct with_iterator_args :
std::conditional<sizeof...(Args) == 2, is_iterator_args<Args...>, std::false_type>::type
{
};
I seem to be able to only make it work by adding more overloads, and not using with_iterator_args:
template <typename T, typename... Args>
void some_func_common(T first, Args&&... args)
{
std::cout << "func(" << first << ") called with " << sizeof...(args) << " args" << std::endl;
}
template <typename T, typename A>
void some_func(T first, A arg)
{
some_func_common(first, arg);
}
template <typename T>
void some_func(T first)
{
some_func_common(first);
}
template <typename T, typename A1, typename A2, typename... Args,
typename = typename std::enable_if<!is_iterator_args<A1, A2>::value>::type>
void some_func(T first, A1 begin, A2 end, Args&&... args)
{
some_func_common(first, std::forward<A1>(begin), std::forward<A2>(end), std::forward<Args>(args)...);
}
template <typename T, typename Begin, typename End,
typename = typename std::enable_if<is_iterator_args<Begin, End>::value>::type>
void some_func(T first, Begin begin, End end)
{
std::cout << "func(" << first << ") called iterators: " << std::distance(begin, end) << std::endl;
}
It seems unnecessarily messy, though.

Can't get std::map to insert from function

I am trying to add items to a map that is a private variable in a class based on if certain parameters are met. When I try to use the insert function for std::map or the [] operator, nothing happens. I don't even get an error. During debugging the code executes like everything is fine but the map stays empty.
I have tried multiple ways to insert to the map including the [] operator and different insert arguments.
class foo {
private:
std::map<std::string, int> map;
public:
void bar();
};
In cpp file:
void foo::bar() {
if(condition)
map.insert(std::make_pair("string", 1));
}
There are no error messages or warnings in the compiler or during debugging.
If the basic STD map usage works, maybe the problem sits in your condition implementation
#include <iostream>
#include <map>
class Foo {
std::map<std::string, int> map;
public:
void bar();
void print();
};
void Foo::bar() {
// if (condition) // weird condition causing failure
map.insert(std::make_pair("string", 1));
}
void Foo::print() {
std::cout << map.size() << std::endl;
std::cout << map.at("string") << std::endl;
}
int main(void) {
Foo foo;
foo.bar();
foo.print();
}

Dynamic function call through member function via map and arguments unpacking through template

I have tried code written on some link provided for dynamic function call , but unable to run code on machine .I tried to run code present at stackoverflow.com/questions/15764078/dynamically-creating-a-c-function-argument-list-at-runtime through member function.
It is is giving bad call exception while running :
Code snnippets
#include <iostream>
#include <functional>
#include <stdexcept>
#include <string>
#include <boost/any.hpp>
class Test;
class Test
{
public:
template <typename Ret, typename... Args>
Ret callfunc (std::function<Ret(Args...)> func, std::vector<boost::any> anyargs);
template <typename Ret>
Ret callfunc (std::function<Ret()> func, std::vector<boost::any> anyargs)
{
if (anyargs.size() > 0)
throw std::runtime_error("oops, argument list too long");
return func();
}
template <typename Ret, typename Arg0, typename... Args>
Ret callfunc (std::function<Ret(Arg0, Args...)> func, std::vector<boost::any>anyargs){
if (anyargs.size() == 0)
throw std::runtime_error("oops, argument list too short");
Arg0 arg0 = boost::any_cast<Arg0>(anyargs[0]);
anyargs.erase(anyargs.begin());
std::function<Ret(Args... args)> lambda =
([=](Args... args) -> Ret {
return func(arg0, args...);
});
return callfunc (lambda, anyargs);
}
template <typename Ret, typename... Args>
std::function<boost::any(std::vector<boost::any>)> adaptfunc (Ret (Test::*func)(Args...)) {
std::function<Ret(Test*,Args...)> stdfunc = func;
std::function<boost::any(std::vector<boost::any>)> result =
([=](std::vector<boost::any> anyargs) -> boost::any {
return boost::any(callfunc(stdfunc, anyargs));
});
return result;
}
int func1 (int a)
{
std::cout << "func1(" << a << ") = ";
return 33;
}
};
int main ()
{
Test a;
std::vector<std::function<boost::any(std::vector<boost::any>)>> fcs =
{
a.adaptfunc(&Test::func1)};
std::vector<std::vector<boost::any>> args =
{{777}};
// correct calls will succeed
for (int i = 0; i < fcs.size(); ++i)
std::cout << boost::any_cast<int>(fcs[i](args[i])) << std::endl;
return 0;
}
This code compiled successfully
But it failed to run and crashed
In main function for loop.
Function needs typecast according to their signature e.g.:
a.adaptfunc((int(*)(int))&Test::func1)};
After this typecast function call will not fail

How to call exported function from dll in C/C++?

My aim is to call some function via its address. How can I do it?
I have done the next work for such aim, but at first(1) - I've got access violation ( don't know why ) and with the second I have some problems with calling function is ASM with ESP value...
The first (the problem with access violation):
#include <iostream>
#include <Windows.h>
const DWORD_PTR offset = 0x00001a90;
typedef void (__stdcall *uef)(int);
int main(void)
{
HMODULE hModule = LoadLibrary(L"C:\\Windows\\system32\\OpenAL32.dll");
DWORD_PTR addr = (DWORD_PTR)hModule + offset;
uef func = (uef)offset;
func(0);
return 0;
}
The second (problems at runtime with ESP value):
#include <iostream>
#include <Windows.h>
typedef void (__stdcall *uef)(int);
int main(void)
{
HMODULE hModule = LoadLibrary(L"C:\\Windows\\system32\\OpenAL32.dll");
uef obj = NULL;
if(hModule != NULL)
{
obj = reinterpret_cast<uef>(GetProcAddress(hModule, "alEnable"));
}
if(obj != NULL)
{
(*obj)(0);
}
if(hModule != NULL)
{
FreeLibrary(hModule);
}
return 0;
}
How could I solve this problem?
PS
And the another main question is:
How can I dynamically calculate the function address in runtime for next calling?
Thanks,
Best Regards!
First, there is a major issue (hence the access violation) with the hardcoded address offset (const DWORD_PTR offset = 0x00001a90). Don't do that! How can you know that the offsett will not be changed because of ASLR?