C++ so why error: no match for 'operator=' - c++

So I am just trying to make an array of objects of my custom class bcLED and I am getting the error.
error: no match for 'operator=' (operand types are 'bcLed' and 'bcLed*')
Can some one tell me why? I know it will be something simple.
also why i am here is there a way to create an array of an unspecified length in C++ and then just append it with an new row each time I want to add an object to it?
void PopulateLEDS(){
int i;
bcLed ledArr[17];
for (i = 0; i< 16; i++)
{
ledArr[i] = new bcLed();
ledArr[i].id = i;
ledArr[i].charge = 0;
}
}
OK so i need more help
To avoided creating ten thousand posts I am going to paste the main body of the code so that to see where I am tripping up with the C++ syntax.
the lattest errors are
/Users/bencawley/Documents/Arduino/Test/Bens_Lights/Bens_Lights.ino: In function 'void PopulateLEDS()':
Bens_Lights:49: error: expected primary-expression before 'public'
public:bcLed ledArr[17];
^
Bens_Lights:52: error: 'ledArr' was not declared in this scope
ledArr[i].id = i;
^
/Users/bencawley/Documents/Arduino/Test/Bens_Lights/Bens_Lights.ino: In function 'void BensPattern(uint8_t)':
Bens_Lights:69: error: 'ledArr' was not declared in this scope
strip.setPixelColor(i,0, 0, ledArr[i].charge, 0);
^
Using library Adafruit_NeoPixel at version 1.0.6 in folder: /Users/bencawley/Documents/Arduino/libraries/Adafruit_NeoPixel
exit status 1
expected primary-expression before 'public'
And my code is:
class bcLed{
public:int id;
public:int charge;
void incCharge(int amt)
{
charge = charge+amt;
if(charge >= 255){charge = 255;}
}
};
void setup() {
strip.begin();
strip.show(); // Initialize all pixels to 'off'
PopulateLEDS();
}
void loop() {
// Some example procedures showing how to display to the pixels:
BensPattern(45);
}
void PopulateLEDS(){
int i;
bcLed ledArr[17];
for (i = 0; i< 17; i++)
{
ledArr[i].id = i;
ledArr[i].charge = 0;
}
}
void BensPattern(uint8_t wait)
{
uint16_t i, j;
int rn = rand() % strip.numPixels() ;
for (i = 0; i<strip.numPixels(); i++)
{
strip.setPixelColor(i,0, 0, 0, 0);
}
for (i = 0; i<rn; i++)
{
strip.setPixelColor(i,0, 0, ledArr[i].charge, 0);
ledArr[i].incCharge(1);
}
strip.show();
delay(wait);
}

new isn't always needed in C++, and definitely not here. new allocates dynamic memory for you if automatic allocation isn't good enough for you. You usually only use new if you want the variable to outlive it's scope. Memory allocated with new must also always be deleted in order to avoid a memory leak. In modern C++, the use of new is even less needed because we have smart pointers.
bcLed ledArr[17];
This already creates 17 bcLeds for you (like how you would use new in C#, requires no cleanup), no need to use new on them. Just work with them.. Your loop condition is wrong too, it's supposed to be < 17.
for (i = 0; i < 17; i++)
{
ledArr[i].id = i;
ledArr[i].charge = 0;
}
also why i am here is there a way to create an array of an unspecified
length in C++ and then just append it with an new row each time I want
to add an object to it?
Yes, that's what a std::vector is for:
#include <vector>
std::vector<bcLed> ledArr(17);
//loop over them:
for(int i = 0; i < ledArr.size(); ++i)
{
//ledArr[i]
}
//or:
for(std::vector<bcLed>::iterator itr = ledArr.begin() itr != ledArr.end(); ++itr)
{
//*itr
}
// to insert to the back of the vector use push_back:
bcLed aLed;
ledArr.push_back(aLed);
If you have access to C++11 you can use a range based loop instead and use emplace_back:
#include <vector>
std::vector<bcLed> ledArr(17);
//loop over them, just to iterate:
for(const auto& led : ledArr)
{
//led.id
//led.charge
}
//appending to the vector:
ledArr.emplace_back(/*constructor arguments*/);
To answer your comment
ok im going to brave and ask this when you say "if you want the
variable to outlive it's scope or you're working with low level
memory" I don't understand what any of that means... well mostly I
don't understand what you mean by scope or low level memory. Could you
explain those? is scope the time that the method runs for?
A scope of a variable is the context in which it is defined. Automatic storage lives until the end of it's scope. Braces { } indicate scope. For example:
void foo()
{
int x;
bcLed aLed;
{ //create a new inner scope
bcLed innerLed;
} //scope ends, all automatic variables are destroyed (innerLed in this case)
//can't use `innerLed` here.
int new_int = x;
} // scope ends, same goes, new_int, x, aLed are destroyed.
Really though, a good book will tell you the differences and when they should be used.

ledArr[i] = new bcLed(); doesn't work, as the error message said, you can't assign an pointer to bcLed (i.e. bcLed*) to a bcLed.
For bcLed ledArr[17];, the 17 elements of array has been default constructed; You don't need to new one at all. So just remove the code causing errors, the following code would work fine.
bcLed ledArr[17];
for (i = 0; i < 16; i++)
{
ledArr[i].id = i;
ledArr[i].charge = 0;
}
is there a way to create an array of an unspecified length in C++ and then just append it with an new row each time I want to add an object to it?
That's what std::vector supposed to do.
If you want to process all the elements of the array, the condition of for should be i < 17.

Related

Is this allowed at runtime? How do you extract the top N elements of a stack-like thing?

I'm trying to do something like this - copy the top N elements of the stack to an array. I want to use it to define the invokevirtual, invokespecial, invokestatic, invokeinterface, and invokedynamic instructions for a Java Ahead-Of-Time Compiler. The stack is a linked list and __pop() unwinds and returns the top of the stack.
public : void __sipop(){
topframe = topframe->prev;
}
public : void __longpop(){
topframe = topframe->prev->prev;
}
public : jvalue __pop(){
//also shared with bytecode
jvalue value = topframe->value;
if(topframe->type == 'J' || topframe->type == 'D'){
__longpop();
} else{
__sipop();
}
return value;
}
public : jvalue* __extract(int count){
jvalue extracted [count];
for(int i = 0; i < count; i++){
extracted[count - i - 1] = __pop();
}
return extracted;
}
Will my implementation crash at runtime?
Will my implementation crash at runtime?
Maybe. You exhibit Undefined Behaviour at least in:
jvalue* __extract(int count){
jvalue extracted [count];
for (int i = 0; i < count; i++){
extracted[count - i - 1] = __pop();
}
return extracted;
}
Your function returns a pointer to a local variable whose lifetime ends as the function returns. For additional information, you should read this excellent answer on Sotack Overflow: Can a local variable's memory be accessed outside its scope? (tl; dr: no).
The simplest solution would be to return a vector:
#include <vector> // preferably in the first lines of your header file (.hpp)
std::vector<jvalue> extract(int count)
{
auto extracted = std::vector<jvalue>(count);
for (int i = 0; i < count; i++) {
extracted[count - i - 1] = __pop();
}
return extracted;
}
You may also be interested by std::generate.
Additionally, as mentioned in the comments, names staring by two underscores (__) are reserved to the implementation.
Unrelated note, I understand your wish to feel comfortable in C++ by mimicking aspects of the Java language, but you should write idiomatic C++ and not repeat the access modifier (public) before each member function.
Yes. Returning the address of a stack-local object (extracted) is undefined behavior. Return a heap-allocated array (auto extracted = new jvalue[count];) or std::vector<jvalue> instead.

c++ 2d array of class pointers

i am trying to create a 2d array holding pointers of my class. first, i'd like to assign all of them NULL:
Timetable::Timetable(int hours) : TimetableBase(hours){
scheduledLectures = new Lecture**[5];
for (int i = 0; i < 5; i++) {
scheduledLectures[i] = new Lecture*[hours];
for (int j = 0; j < hours; j++)
scheduledLectures[i][j] = NULL;
};
}
this is for a timetable generator application. i have a function to set these pointers to a specific object.
void Timetable::setLecture(Lecture& lecture){
while ((lecture.getDuration()) -1 > 0){
scheduledLectures[lecture.getDayScheduled()][(lecture.getHourScheduled())+1] = &lecture;
}
}
the compiler returns no errors for this, but when its running, it seems that the pointers remain NULLs.
i am sure the error is inside the setter function (and almost sure that its a grammar mistake) but i cannot find the solution for that.
whats wrong in here?
thank you
Use a vector (or std::array) of pointers or shared_ptrs (or unique_ptrs depending on how your lifetimes are arranged) instead of a 2D array of pointers that you manage yourself. Save yourself the trouble of managing the memory and lifetimes of your objects manually.
class TimeTable {
vector<vector<shared_ptr<Lecture>>> scheduledLectures;
};
Timetable::Timetable(int hours)
: TimetableBase(hours),
scheduledLectures(5, vector<shared_ptr<Lecture>>(5)) {}
void Timetable::setLecture(std::shared_ptr<Lecture> lecture){
while ((lecture->getDuration()) -1 > 0) { // not sure what this does
scheduledLectures[lecture->getDayScheduled()][(lecture->getHourScheduled())+1] = lecture;
}
}
You can test whether a shared_ptr is null like follows
auto s_ptr = std::shared_ptr<int>{}; // null
// either assign it to a value or keep it null
if (s_ptr) {
// not null
}
If you are managing the memory of the Lecture objects elsewhere then just use a 2D vector of pointers and trust your code
class TimeTable {
vector<vector<Lecture*>> scheduledLectures;
};
Timetable::Timetable(int hours)
: TimetableBase(hours),
scheduledLectures(5, vector<Lecture*>(5)) {}
void Timetable::setLecture(Lecture& lecture){
while ((lecture.getDuration()) -1 > 0) { // not sure what this does
scheduledLectures[lecture.getDayScheduled()][(lecture.getHourScheduled())+1] = &lecture;
}
}

Trying to fill a 2d array of structures in C++

As above, I'm trying to create and then fill an array of structures with some starting data to then write to/read from.
I'm still writing the cache simulator as per my previous question:
Any way to get rid of the null character at the end of an istream get?
Here's how I'm making the array:
struct cacheline
{
string data;
string tag;
bool valid;
bool dirty;
};
cacheline **AllocateDynamicArray( int nRows, int nCols)
{
cacheline **dynamicArray;
dynamicArray = new cacheline*[nRows];
for( int i = 0 ; i < nRows ; i++ )
dynamicArray[i] = new cacheline [nCols];
return dynamicArray;
}
I'm calling this from main:
cacheline **cache = AllocateDynamicArray(nooflines,noofways);
It seems to create the array ok, but when I try to fill it I get memory errors, here's how I'm trying to do it:
int fillcache(cacheline **cache, int cachesize, int cachelinelength, int ways)
{
for (int j = 0; j < ways; j++)
{
for (int i = 0; i < cachesize/(cachelinelength*4); i++)
{
cache[i][ways].data = "EMPTY";
cache[i][ways].tag = "";
cache[i][ways].valid = 0;
cache[i][ways].dirty = 0;
}
}
return(1);
}
Calling it with:
fillcache(cache, cachesize, cachelinelength, noofways);
Now, this is the first time I've really tried to use dynamic arrays, so it's entirely possible I'm doing that completely wrong, let alone when trying to make it 2d, any ideas would be greatly appreciated :)
Also, is there an easier way to do write to/read from the array? At the moment (I think) I'm having to pass lots of variables to and from functions, including the array (or a pointer to the array?) each time which doesn't seem efficient?
Something else I'm unsure of, when I pass the array (pointer?) and edit the array, when I go back out of the function, will the array still be edited?
Thanks
Edit:
Just noticed a monumentally stupid error, it should ofcourse be:
cache[i][j].data = "EMPTY";
You should find your happiness. You just need the time to check it out (:
The way to happiness

Simple loop, which one I would get more performance and which one is recommended? defining a variable inside a loop or outside of it?

Variable outside of the loop
int number = 0;
for(int i = 0; i < 10000; i++){
number = 3 * i;
printf("%d",number);
}
or Variable inside of the loop
for(int i = 0; i < 10000; i++){
int number = 3 * i;
printf("%d",number);
}
Which one is recommended and which one is better in performance?
Edit:
This is just an example to exhibit what I mean, All I wanna know is if defining a variable inside a loop and outside a loop means the same thing , or there's a difference.
Time to learn something early: any optimization you could make on something like this will be irrelevant in the face of printf.
Printf will be very, very slow. You could quintuple the math and get no measurable speed decrease. It's just the nature of printing to the terminal.
As for your edited question, there is no difference defining it in the loop or out. Imagine that
for (i = 0; i < 500; i++) {
int a = i * 3;
}
is just the same as
int forloop::a; // This doesn't work, the idea is to show it just changes the scope
for (i = 0; i < 500; i++) {
a = i * 3;
}
They will produce identical code, unless you start needing to use that variable outside of the loop it is defined in, because it is defined in the local scope of the loop. So...more like this:
int forloop::a; // Still not valid code, just trying to show an explanation
namespace forloop {
for (i = 0; i < 500; i++) {
a = i * 3;
}
} // namespace forloop
If this is unclear please let me know I'll go into more detail or explain differently.
Do not bother you with performance at first: make it safe before everything.
I would just quote Scott Meyers (Effective C++) for your concern:
"Postpone declarations as far as you can".
Thus, the second pattern is safer.
Example:
int j = 0;
for(int i = 0; i < 10000; i++){
j = 3 * i;
printf("%d",j);
}
...
// Use of j out of control!!!
int k = j * 5;
Now with the second pattern:
for(int i = 0; i < 10000; i++){
int j = 3 * i;
printf("%d",j);
}
...
// j not declared at this point.
// You get informed of the mistake at compile time, which is far much better.
int k = j * 5;
You do have a C++ tag, and you mention "declaring a string" in the question. Therefore there might be a performance difference (and yes, the printf could swamp it). Declaring a non-simple variable means calling a constructor, which might mean a non-trivial amount of work. In that case, declaring it inside of the loop could be hiding significant work in what appears to be an innocent declaration.
In general, the answer is that if you really care about performance - and treating the sample code as only an example of the difference between two places to declare a variable - then for non-simple variables, it is better to declare it outside the loop, unless the semantics require a fresh version of a temporary at each iteration.
There are likely many other places first to look at if performance is an issue, but one consideration is always moving loop invariants out of loops, especially if it is much easier for you to tell that it is invariant than for the compiler. And what looks like a declaration, can, in C++, fall into that category.
If, for (silly) example, you have
int k = 43;
for ( int i = 0; i < N; ++i )
{
int j = 17 + k; // k was previously defined outside the loop, but doesn't change in it
l = j * j; // l was also declared outside the loop
}
any good optimizing compiler can recognize that k is constant, and that j is always assigned 60, and l is assigned 3600 N times, and the loop can simply be removed and replaced with a single assignment to l. Here k and j are both loop invariants.
But a not-quite-so-good compiler might miss even one link in that chain, and wind up creating the loop.
It gets harder for the compiler to figure things out when you have
Foo k( 43 ); // a class that takes an int argument to its constructor
for( int i = 0; i < N; ++i )
{
Bar j( k ); // a Bar takes an int argument, adds 17 and stores it.
l = j.squared();
}
Same invariants. Not as easy to detect without looking inside the workings of bar; and if the constructor and squared method aren't inline, we've just made it slower.
In this case, printf("%d", i * 3) would be better than defining the variable at all.
To answer your question and not nitpicking:
The difference between the 2 variants is, that you are declaring your variable number in different "variable environments" - by which I mean that the scope changes. A variable environment is given by your curly braces { ... }. Everytime you open a new curly brace like this { ... { ... } ... }, you declare a new variable environment inside the old one, which means, that if you declare numbers like so:
{ ... { int numbers; ... } ... }
this variable will only be visible or existent in the innermost environment. So
{ ... { int numbers; ... } ... do_something(numbers); ... }
will give a compiler error.
And to your concerns about performance: Neither variant is better performing. Most, if not all compilers will give the same assembly.

weird issue in an SDL-based Hanoi Tower Game

I want to create a SDL-based Hanoi Tower Game, but before I proceed to writing "engine", I wanted to test my Hanoi in a console. Surprisingly, it turned out to be quite buggy.
CTower tower[3];
tower[0] = CTower(3);
tower[1] = CTower(3);
tower[2] = CTower(3);
init(&tower[0]); //prepare first tower
tower[0].Print();
This piece of code should create 3 arrays (of size 3) and fill 'em with 0 (zeros). Then, in init(), I prepare the first tower (fill it with vaild discs). However simple may it seem, my application halts on printing and doesn't fill the remaining arrays (with 0). What's strange, function init() works just fine.
I would appreciate any help.
Here's some code to check:
class CTower {
uint16 *floors, floorsNum;
void Init();
public:
(...) //definitions, probably of zero importance
};
void CTower::Init() {
//private member, filling with zeros
for (uint16 i = 0; i < floorsNum; i++)
floors[i] = 0;
}
CTower::CTower() {
//default initialiazer
floors = NULL;
floorsNum = 0;
}
CTower::CTower(uint16 nfloors) {
floors = new uint16[nfloors];
floorsNum = nfloors;
this->Init();
}
CTower::~CTower() {
delete[] floors;
floorsNum = 0;
}
void CTower::Print() {
if (floorsNum == 0) printf("EMPTY TOWER!");
else
for (uint16 i = 0; i < floorsNum; i++)
printf("%d\n", floors[i]);
}
void init(CTower *tower) {
//a friend method of CTower
for (uint16 i = 0; i < tower->floorsNum; i++)
tower->floors[i] = i+1;
}
My application source: https://rapidshare.com/files/2229751163/hanoi-tower.7z
Problem is with your initialisation and allocation of your class. It seems you have forgotten that Resource Acquisition is Initialisation.
You are facing a free corruption : you call delete[] on a not allocated attribute.
You have this constructor :
CTower::CTower() {
//default initialiazer
floors = NULL;
floorsNum = 0;
}
Which does NOT allocates memory but which is destroyed with :
CTower::~CTower() {
delete[] floors;
floorsNum = 0;
}
A simple way to fix your program is to allocate directly with the working constructor :
int main(void) {
CTower tower[3] = { CTower(3), CTower(3), CTower(3) };
init(&tower[0]);
tower[0].Print();
printf("\n");
tower[1].Print();
return 0;
}
But it would be far better to also fix your Class, either in Destructor or in Constructor part.
Unless you have been specifically asked not to use a std::vector then I would consider changing your code to use one as it makes life a lot simpler.
With regards to your specific code example. You are going to have problems due to the lack of a copy constructor and assignment operator as the defaults generated by the compiler are not going to be suitable for your class.
I would also consider getting rid of the friend function void init(CTower *tower) as this really isn't good practice.
I would provide a code example but this question is tagged as "Homework" so I will let you do the research yourself.