I am new to c++ in general. So I have been trying to learn about using vectors after someone recently helped with using an Arduino type project to read RFID tags. It really got me thinking I have no clue how to program. So I hit the books!
So here is the question: When I do the following code:
#include <iostream>
#include <vector>
struct Runner{
char runnerTag[32];
uint32_t ts;
};
std::vector<Runner > runners;
int main() {
std::cout << "Hello, Runners!\n";
for (int i = 0; i < 100; i++) {
std::string runnertg = "testTrackTag01";
uint32_t timeStamp = rand() % 100 + 1;
runners[i] = new Runner({runnertg, timeStamp});
}
return 0;
}
I get this annoying little message from xcode:
No matching constructor for initialization of 'Runner'
on line 16 of the above snippet. What in the world am I doing wrong?
The expression new Runner({runnertg, timeStamp})
has a type mismatch. runnertg
is of type std::string
, while the element Runner::runnerTag
is of type char[32]
.
The expression runners[i] = new Runner({runnertg, timeStamp});
has another type mismatch. The element type of runners
is Runner
, while the expression new Runner({runnertg, timeStamp})
is of type Runner*
.
runners[i]
is out-of-bound access. The size of runners
is 0. The elements runners[i]
for all values of i
does not exist.
There is memory leak since there is no matching delete
for each new
for all code path.
Don't use rand()
.
A lot of the code you're using is old style C with some C++ STL code mixed in. I will try and tackle a few issues one at at time.
struct
is an abstract data type used (in general) to organise primitive data types. While the only difference between a struct
and a class
is that the latter defaults all members to private and in this case is not functional, it's a good to cut these things of at the pass.
Secondly, an array of char
s is cumbersome, messy and prone to error. Try an std::string
instead.
Finally, let's create a constructor taking our two parameters.
Thus:
#include <string>
class Runner {
public:
std::string runnerTag;
uint32_t ts;
Runner(std::string, uint32_t);
};
Next thing. Using an array index operator []
to access or modify an std::vector
is dangerous and defeats the purpose of using a container and all the wonderful functionality that comes along with it.
Since you know for loops, let's try this:
for (int i = 0; i < 100; i++) {
std::string runnertg = "testTrackTag01";
uint32_t timeStamp = rand() % 100 + 1;
Runner Runner(runnertg, timeStamp);
runners.push_back(Runner);
}
At the end of your code, outside the scope of the main function, define the constructor as follows:
Runner::Runner(std::string rt, uint32_t ts) {
runnerTag = rt;
ts = ts;
}
This should get you started.
You cannot convert std::string
to a char
array like that. Change the type of the member variable runnerTag
to std::string
. Also, you are accessing vector elements that don't exist. Use resize
to create them. Or better yet, use emplace_back
to do both at once. Also, don't use int
to iterate containers, but std::size_t
. Also, don't use rand()
, but the classes from the <random>
header. That trick using % creates a non-uniform distribution.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.