Displays nothing when debugged [duplicate] - c++

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to pass objects to functions in C++?
Main class
#include "List.h"
#include "Car.h"
#include "Worker.h"
#include "Queue.h"
#include <iostream>
#include <string>
using namespace std;
void initWorkerList(List<Worker>);
void initCarList(List<Car>, Queue, Queue);
int main() {
List<Worker> WorkerList;
List<Car> CarList;
Queue q1, q2;
initWorkerList(WorkerList);
initCarList(CarList, q1, q2); // Error here
//..... e.g cout << "Successful!"; but it does not displays it...
}
void initWorkerList(List<Worker> WorkerList) {
Worker w1 = Worker("Ben Ang", "Ben123", "pass123", 'M');
WorkerList.add(w1);
Worker w2 = Worker("Grace Eng", "Gr4ce", "loveGrace", 'W');
WorkerList.add(w2);
Worker w3 = Worker("Rebecca Xuan", "Xuanz", "Rebecca Xuan", 'W');
WorkerList.add(w3);
}
void initCarList(List<Car> CarList, Queue q1, Queue q2) {
Car c1 = Car("SJS1006Z","Toyota", "Saloon car");
Car c2 = Car("SFW6666E", "hyundai", "Taxi (Saloon)");
Car c3 = Car("SCF1006G","Mercedes", "Large Van");
Car c4 = Car("SBQ1006Z", "Puma", "Saloon Car");
q1.enqueue(c1);
q2.enqueue(c1);
q2.enqueue(c3);
q1.enqueue(c4);
q1.enqueue(c1);
q1.enqueue(c1);
q1.enqueue(c1);
q2.enqueue(c2);
q2.enqueue(c2);
}
There is no error at all. But nothing is displayed when being debugged...I have tried and my guess is there is something wrong with initCarList(CarList,q1,q2); cause after that code, other codes can work at all. Is there anything wrong with it? Thanks

You are passing the Queue Variables by value rather than by reference.
initCarList(CarList, q1, q2); // Error here
So any change in initCarList wont get reflected back to caller
Change your function signature to
void initCarList(List<Car> CarList, Queue& q1, Queue& q2) {
and the declaration to
void initCarList(List<Car>, Queue&, Queue&);
If you pass parameter by value, any change within initCarList is local to the function scope and does not get reflected back.
Pass by Value
Caller Callee
|------| |------|
workedList workedList
| ___ | | ___ |
|| | |--------> || | | <------
||___| | ||___| | |
| | | | |
|q1 | |q1 | (Changing any of these variables
| ___ | | ___ | won't be reflected back)
|| | |--------> || | | |
||___| | ||___| | |
| | | | |
|q2 | |q2 | |
| ___ | | ___ | |
|| | |--------> || | | |
||___| | ||___| | <------
|______| |______|
Pass by reference
Caller Callee
-------- --------
|wList | |wList |
| ___ | | ____ |
|| | |--------> || || <------
||___|<|------------||-*__|| |
| _ | | | |
|q1 | |q1 | (Changing any of these variables
| ___ | | ____ | will be reflected back)
|| | |--------> || || |
||___|<|------------||-*__|| |
| | | | |
|q2 | |q2 | |
| ___ | | ____ | |
|| | |--------> || || |
||___|<|------------||-*__|| <------
|______| |______|

You're passing your variables in by value, which means that the function's parameters hold a copy of them, which you modify and discard when the function ends. Pass by reference instead to modify the original variable. For example, initCarList would become:
void initCarList(List<Car> CarList, Queue &q1, Queue &q2)
You also don't use the CarList parameter, so you might as well take it out if this is how it is in your code.

Your functions pass by value which means functions make a copy of passed in variables and manipulate on the copied ones. To modify on original ones you need to pass parameter by reference
Change:
void initWorkerList(List<Worker>);
void initCarList(List<Car>, Queue, Queue);
To:
void initWorkerList(List<Worker> &);
void initCarList(List<Car>&, Queue&, Queue&);

Related

Concatenating string_view objects

I've been adding std::string_views to some old code for representing string like config params, as it provides a read only view, which is faster due to no need for copying.
However, one cannot concatenate two string_view together as the operator+ isn't defined. I see this question has a couple answers stating its an oversight and there is a proposal in for adding that in. However, that is for adding a string and a string_view, presumably if that gets implemented, the resulting concatenation would be a std::string
Would adding two string_view also fall in the same category? And if not, why shouldn't adding two string_view be supported?
Sample
std::string_view s1{"concate"};
std::string_view s2{"nate"};
std::string_view s3{s1 + s2};
And here's the error
error: no match for 'operator+' (operand types are 'std::string_view' {aka 'std::basic_string_view<char>'} and 'std::string_view' {aka 'std::basic_string_view<char>'})
A view is similar to a span in that it does not own the data, as the name implies it is just a view of the data. To concatenate the string views you'd first need to construct a std::string then you can concatenate.
std::string s3 = std::string(s1) + std::string(s2);
Note that s3 will be a std::string not a std::string_view since it would own this data.
A std::string_view is an alias for std::basic_string_view<char>, which is a std::basic_string_view templated on a specific type of character, i.e. char.
But what does it look like?
Beside the fairly large number of useful member functions such as find, substr, and others (maybe it's an ordinary number, if compared to other container/string-like things offered by the STL), std::basic_string_view<_CharT>, with _CharT being the generic char-like type, has just 2 data members,
// directly from my /usr/include/c++/12.2.0/string_view
size_t _M_len;
const _CharT* _M_str;
i.e. a constant pointer to _CharT to indicate where the view starts, and a size_t (an appropriate type of number) to indicate how long the view is starting from _M_str's pointee.
In other words, a string view just knows where it starts and how long it is, so it represents a sequence of char-like entities which are consecutive in memory. With just two such memebrs, you can't represent a string which is made up of non-contiguous substrings.
Yet in other words, if you want to create a std::string_view, you need to be able to tell how many chars it is long and from which position. Can you tell where s1 + s2 would have to start and how many characters it should be long? Think about it: you can't, becase s1 and s2 are not adjacent.
Maybe a diagram can help.
Assume these lines of code
std::string s1{"hello"};
std::string s2{"world"};
s1 and s2 are totally unrelated objects, as far as their memory location is concerned; here is what they looks like:
&s2[0]
|
| &s2[1]
| |
&s1[0] | | &s2[2]
| | | |
| &s1[1] | | | &s2[3]
| | | | | |
| | &s1[2] | | | | &s2[4]
| | | | | | | |
| | | &s1[3] v v v v v
| | | | +---+---+---+---+---+
| | | | &s1[4] | w | o | r | l | d |
| | | | | +---+---+---+---+---+
v v v v v
+---+---+---+---+---+
| h | e | l | l | o |
+---+---+---+---+---+
I've intentionally drawn them misaligned to mean that &s1[0], the memory location where s1 starts, and &s2[0], the memory location where s2 starts, have nothing to do with each other.
Now, imagine you create two string views like this:
std::string_view sv1{s1};
std::string_view sv2(s2.begin() + 1, s2.begin() + 4);
Here's what they will look like, in terms of the two implementation-defined members _M_str and _M_len:
&s2[0]
|
| &s2[1]
| |
&s1[0] | | &s2[2]
| | | |
| &s1[1] | | | &s2[3]
| | | | | |
| | &s1[2] | | | | &s2[4]
| | | | | | | |
| | | &s1[3] v v v v v
| | | | +---+---+---+---+---+
| | | | &s1[4] | w | o | r | l | d |
| | | | | +---+---+---+---+---+
v v v v v · ^ ·
+---+---+---+---+---+ · | ·
| h | e | l | l | o | +---+ ·
+---+---+---+---+---+ | · ·
· ^ · | · s2._M_len ·
· | · | <----------->
+---+ · |
| · · +-- s2._M_str
| · s1._M_len ·
| <------------------->
|
+-------- s1._M_str
Given the above, can you see what's wrong with expecting that
std::string_view s3{s1 + s2};
works?
How can you possible define s3._M_str and s3._M_len (based on s1._M_str, s1._M_len, s2._M_str, and s2._M_len), such that they represent a view on "helloworld"?
You can't because "hello" and "world" are located in two unrelated areas of memory.
std::string_view does not own any data, it is only a view. If you want to join two views to get a joined view, you can use boost::join() from the Boost library. But result type will be not a std::string_view.
#include <iostream>
#include <string_view>
#include <boost/range.hpp>
#include <boost/range/join.hpp>
void test()
{
std::string_view s1{"hello, "}, s2{"world"};
auto joined = boost::join(s1, s2);
// print joined string
std::copy(joined.begin(), joined.end(), std::ostream_iterator(std::cout, ""));
std::cout << std::endl;
// other method to print
for (auto c : joined) std::cout << c;
std::cout << std::endl;
}
C++23 has joined ranges in the standard library with the name of std::ranges::views::join_with_view
#include <iostream>
#include <ranges>
#include <string_view>
void test()
{
std::string_view s1{"hello, "}, s2{"world"};
auto joined = std::ranges::views::join_with_view(s1, s2);
for (auto c : joined) std::cout << c;
std::cout << std::endl;
}

How does this code work? The result doesnt make sense to me and doesnt appear in the debugger [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed last year.
Improve this question
#include <iostream>
using namespace std;
int f(int n, int m){
if (n==1)
return 0;
else
return f(n-1, m) + m;
}
int main()
{
cout << f(3874, 1000);
cout << endl;
return 0;
}
The result is 3873000. Why is n multiplied by m after deducting 1 and how does the function work in detail please?
The else block is executed at all levels of recursion, except the deepest one.
The number of levels in the recursion tree is n. So we have n-1 times that the else block is executed.
This else block first makes the recursive call, and then adds m to the result it gets back, and returns that sum to the caller, who will do the same, ...etc until the walk upwards the recursion tree is complete.
The original caller will thus see a base number (0) to which m was repeatedly added, exactly n-1 times.
So the function calculates m(n-1), provided that n is greater than 0. If not, the recursion will run into a stack overflow error.
Visualisation
To visualise this, let's split the second return statement into two parts, where first the result of the recursive call is stored in a variable, and then the sum is returned. Also, let's take a small value for n, like 3.
So this is then the code:
int f(int n, int m){
if (n==1)
return 0;
else {
int result = f(n-1, m)
return result + m;
}
}
int main()
{
cout << f(3, 10);
}
We can imagine each function execution (starting with main) as a box (a frame), in which local variables live their lives. Each recursive call creates a new box, and when return is executed that box vanishes again.
So we can imagine the above code to execute like this:
+-[main]----------------------------+
| f(3, 10) ... |
| +-[f]-------------------------+ |
| | n = 3, m = 10 | |
| | f(3-1, 10) ... | |
| | +-[f]-------------------+ | |
| | | n = 2, m = 10 | | |
| | | f(2-1, 10) ... | | |
| | | +-[f]-------------+ | | |
| | | | n = 1, m = 10 | | | |
| | | | return 0 | | | |
| | | +-----------------+ | | |
| | | result = 0 | | |
| | | return 0 + 10 | | |
| | +-----------------------+ | |
| | result = 10 | |
| | return 10 + 10 | |
| +-----------------------------+ |
| cout << 20 |
+-----------------------------------+
I hope this clarifies it.
The algorithm solves the recurrence
F(n) = F(n-1) + m
with
F(1) = 0.
(I removed m as an argument, as its value is constant).
We have
F(n) = F(n-1) + m = F(n-2) + 2m = F(n-3) + 3m = ... = F(1) + (n-1)m.
As written elsewhere, the recursion depth is n, which is dangerous.

How is deque implemented in c++ stl

I just wanted to know how deque is implemented and how are the basic operations like push_front and random access operator are provided in that implementation.
I just wanted to know how deque is implemented
It's always a good to have an excuse for doing ASCII art:
+-------------------------------------------------------------+
| std::deque<int> |
| |
| subarrays: |
| +---------------------------------------------------------+ |
| | | | | | | |
| | int(*)[8] | int(*)[8] | int(*)[8] |int(*)[8]|int(*)[8] | |
| | | | | | | |
| +---------------------------------------------------------+ |
| / \ |
| / \ |
| / \ |
| / \ |
| / \ |
| / \ |
| / \ |
| / \ |
| - - |
| +------------------------------+ |
| | ?, ?, 42, 43, 50, ?, ?, ?, ? | |
| +------------------------------+ |
| |
| additional state: |
| |
| - pointer to begin of the subarrays |
| - current capacity and size |
| - pointer to current begin and end |
+-------------------------------------------------------------+
how are the basic operations like push_front and random access operator are provided in that implementation?
First, std::deque::push_front, from libcxx:
template <class _Tp, class _Allocator>
void
deque<_Tp, _Allocator>::push_front(const value_type& __v)
{
allocator_type& __a = __base::__alloc();
if (__front_spare() == 0)
__add_front_capacity();
__alloc_traits::construct(__a, _VSTD::addressof(*--__base::begin()), __v);
--__base::__start_;
++__base::size();
}
This obviously checks whether the memory already allocated at the front can hold an additional element. If not, it allocates. Then, the main work is shifted to the iterator: _VSTD::addressof(*--__base::begin()) goes one location before the current front element of the container, and this address is passed to the allocator to construct a new element in place by copying v (the default allocator will definitely do a placement-new).
Now random access. Again from libcxx, std::deque::operator[] (the non-const version) is
template <class _Tp, class _Allocator>
inline
typename deque<_Tp, _Allocator>::reference
deque<_Tp, _Allocator>::operator[](size_type __i) _NOEXCEPT
{
size_type __p = __base::__start_ + __i;
return *(*(__base::__map_.begin() + __p / __base::__block_size) + __p % __base::__block_size);
}
This pretty much computes an index relative to some start index, and then determines the subarray and the index relative to the start of the subarray. __base::__block_size should be the size of one subarray here.

Mockito verifying method invocation without using equals method

While using Spock i can do something like this:
when:
12.times {mailSender.send("blabla", "subject", "content")}
then:
12 * javaMailSender.send(_)
When i tried to do same in Mockito:
verify(javaMailSender,times(12)).send(any(SimpleMailMessage.class))
I got an error that SimpleMailMessage has null values, so i had to initialize it in test:
SimpleMailMessage simpleMailMessage = new SimpleMailMessage()
simpleMailMessage.setTo("blablabla")
simpleMailMessage.subject = "subject"
simpleMailMessage.text = "content"
verify(javaMailSender,times(12)).send(simpleMailMessage))
Now it works but it's a large workload and i really don't care about equality. What if SimpleMailMessage will have much more arguments or another objects with another arguments, meh. Is there any way to check that send method was just called X times?
EDIT: added implementation of send method.
private fun sendEmail(recipient: String, subject: String, content: String)
{
val mailMessage = SimpleMailMessage()
mailMessage.setTo(recipient)
mailMessage.subject = subject
mailMessage.text = content
javaMailSender.send(mailMessage)
}
There are 2 senders, mailSender is my custom object and javaMailSender is from another libary
Stacktrace:
Mockito.verify(javaMailSender,
Mockito.times(2)).send(Mockito.any(SimpleMailMessage.class))
| | | | |
| | | | null
| | | Wanted but not invoked:
| | | javaMailSender.send(
| | | <any org.springframework.mail.SimpleMailMessage>
| | | );
| | | -> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
| | |
| | | However, there were exactly 2 interactions with this mock:
| | | javaMailSender.send(
| | | SimpleMailMessage: from=null; replyTo=null; to=blabla; cc=; bcc=; sentDate=null; subject=subject; text=content
| | | );
| | | -> at MailSenderServiceImpl.sendEmail(MailSenderServiceImpl.kt:42)
| | |
| | | javaMailSender.send(
| | | SimpleMailMessage: from=null; replyTo=null; to=blabla; cc=; bcc=; sentDate=null; subject=subject; text=content
| | | );
If you don't care for the parameter of send, leave any() empty:
verify(javaMailSender,times(12)).send(any())

how does the value of variable get changed through swap function? [duplicate]

This question already has answers here:
C++ Swapping Pointers
(7 answers)
Closed 6 years ago.
Here I have two swap functions
void kswap(int* a, int* b)
{
int* temp = a;
a = b;
b = temp;
}
void kswap(int* a, int* b)
{
int temp = *a;
*a = *b;
*b = temp;
}
The value only changed inside of the first function,
and the second function change the value permanently..
Can anyone tell me the different between two functions?
I thought as both functions take pointer type through parameter, the value would be changed through both functions..
In function swap, a and b are int *, aka integer pointers, that means
they contain address of an integer in memory. As seen in diagram below:
Memory
==================
+----------------+
| |
+------> | num1 = 5 |
| | |
| +----> | num2 = 6 |
| | | |
| | | |
| | |================|
| | | Function swap |
| | | |
+-(------------ a |
| | |
+------------ b |
| |
+----------------+
Here,
`*a` : should be read as : `value at address contined in a`
`*b` : should be read as : `value at address contined in b`
In first example
In first kswap, after executing below statements,
int* temp = a; /* A pointer which points to same place as 'a' */
a = b; /* 'a' will now point to where 'b' is pointing */
b = temp; /* 'b' will now point to where 'temp' is pointing
* that means where 'a' was previously pointing */
the result is:
Memory
==================
+----------------+
| |
+------> | num1 = 5 | <------+
| | | |
| +----> | num2 = 6 | |
| | | | |
| | | | |
| | |================| |
| | | Function swap | |
| | | | |
+ +------------ a | |
| | | |
+-------------- b | |
| | |
| temp -----------------+
+----------------+
Note that, neither *a or *b is assigned any value, so neither of:
`*a` : that is : `value at address contined in a`
`*b` : that is : `value at address contined in b`
are changed.
So as seen in above picture, num1 is still 5, and num2 is still 6.
Only thing that has happended is that a is pointing to num2, and b is
pointing to num1.
In second example
In second kswap, after executing below statements,
int temp = *a; /* An int variable which will contain the same value as the
* value at adress contained in a */
*a = *b; /* value at address contained in 'a' will be equal to value
* at address contained in 'b' */
*b = temp; /* value at address contained in 'b' will be equal to value
* contained in 'temp' */
the result is:
Memory
==================
+----------------+
| |
+------> | num1 = 6 |
| | |
| +----> | num2 = 5 |
| | | |
| | | |
| | |================|
| | | Function swap |
| | | |
+-(------------ a |
| | |
+------------ b |
| |
| temp = 5 |
+----------------+
Note that, both *a or *b are assigned new value, so both:
`*a` : that is : `value at address contained in a`
`*b` : that is : `value at address contained in b`
are changed.
And as seen in above picture, num1 is now 6, and num2 is now 5. So in the second example, values of variables num1 and num2 are permanently changed.
Assume each function is called as:
void f()
{
int x = 101, y = 999;
kswap(&x, &y);
}
Remember that in C++ arguments are passed by value, so kswap receives the values of the addresses where x, y reside. The rest of the answer is inlined in the code comments below.
The kswap that works.
void kswap(int* a, int* b)
{
int temp = *a; // `a` is the address of `int x`
// `*a` is the integer value at address `a`
// i.e. the value of `x` so temp == 101 now
*a = *b; // same as above `*b` is the value of `y` i.e. 999
// now this integer value is copied to the address where `a` points
// effectively overwriting the old `x` value `101` with `999`
*b = temp; // finally, this copies the value in `temp` i.e. 101
// to the address where `b` points and overwrites
// the old `y` value `999`, which completes the swap
}
The kswap which does not work.
void kswap(int* a, int* b)
{
int* temp = a; // this copies `a` i.e. the address of `x`
// to local variable `temp`
a = b; // this copies `b` to `a`
// since arguments `a` and `b` are pointers and passed by value
// this only modifies the value of variable `a`
// it does **not** change `x` or its address in any way
b = temp; // this copies 'temp' to 'b', same comments as above
// now 'a' holds the address of `y` and `b` holds the address
// of `x` but **neither** 'x' nor 'y' values have been modified
// and pointer variables `a`, `b` go out of scope as soon as
// the function returns, so it's all a big no-op in the end
}
The first function swaps the addresses, but not outside the scope of the function.
The second function swaps the values, and outside the function's scope.
Adding the * to the name, means you want the value, not where it's at.