I am solving a problem and came across this obstacle .
Why this code gives me an error
queue<node>q;
node n;
q.push(n);
q.push(NULL);
'no matching function for call to 'std::queue::push(NULL)'
And when I do this change
queue<node*>q;
node* n = new node();
q.push(n);
q.push(NULL);
It works Fine!
Related
I am fairly new to developing smartcontracts and have run into an issue while testing. My intention is to ensure the smartcontract cannot mint more than 13 ERC721 tokens. My understanding is that a require function can have a second string argument that will revert a string as an error if the require condition is not met. Is this correct?
The following is my smart contract code:
contract TheCondemned_Episode is ERC721Enumerable {
string[] public episodes;
constructor() ERC721("TheCondemned_e1", "TCe1") public {
}
function mint(string memory _episode) public {
require(episodes.length <= 13, "Cannot make more than 13 episodes");
episodes.push(_episode);
uint _id= episodes.length;
_mint(msg.sender, _id);
}
}
And the test I am running is as follows:
it('Cannot create more than 13 episodes', async() => {
for(var i=0; i===13; i++){
var episode= `Episode ${i}`
await contract.mint(episode)
}
try {
await contract.mint('Episode 14');
assert(true);
}
catch (err) {
return;
}
assert(false, "The contract did not throw.");
The test fails and returns "The contract did not throw". What is the best practice in regards to catching a revert string from a failed require condition when testing?
My understanding is that a require function can have a second string argument that will revert a string as an error if the require condition is not met. Is this correct?
That's correct. Here's an example of an always failing require() condition that throws an exception with the error message.
require(false, 'Error message');
However, you have a logical error in the Solidity require() condition, as well as in the JS test snippet.
First, let's uncover the Solidity code. For simplicity, let's assume you're allowing to mint only 1 episode.
require(episodes.length <= 1, "Cannot make more than 1 episode");
First iteration (expected to pass)
episodes.length is 0, that's <= 1. Condition passes, you mint the first token, and then push to the episodes array, so its length becomes 1 after the condition.
Second iteration (expected to fail)
episodes.length is 1, that's still <= 1. So the condition passes as well.
Solution: Replace the <= (less than or equal) to just < (less than).
require(episodes.length < 1, "Cannot make more than 1 episode");
First iteration (expected to pass)
episodes.length is 0, that's < 1. Condition passes, you mint the first token, and then push to the episodes array, so its length becomes 1 after the condition.
Second iteration (expected to fail)
episodes.length is 1, which fails the condition 1 < 1, as you expect.
I'm assuming that your intention in the JS snippet is to call the mint() function 13 times in the loop, and then 14th time in the try/catch block.
However, the loop currently doesn't perform any iteration. So in fact, you're only executing the mint() function once (in the try/catch block).
The second parameter in the for loop is a condition stating "this loop will keep iterating for as long as this condition is met". But since you set the value of i to 0 in the first parameter, the loop condition (i===13) is not met, and the loop doesn't perform even the first iteration.
Solution: Check whether the i is "less than 13" instead of just "equals 13".
for(var i = 0; i < 13; i++) {
This way, the loop will iterate 13 times.
Suppose I'm using a package function f that takes a single argument x and performs some error checking on that argument. Like, is x of the right type? Etc. And if there is an error then f(x) throws an error with Error().
Is there an easy way to write a wrapper function fCatch around f to catch that error, and say return false if f(x) throws an error but true otherwise? The naïve way to accomplish this same effect would be to copy the code for f and change all the Error(...); lines into a return false; and set a return true; at the end, but it's bad form to duplicate all the error-checking code.
As per Alexander Konovalov's comment, the following works, except the Error(...) message that f(x) triggers still prints.
fCatch := function(x)
local result;
BreakOnError := false;
result := CALL_WITH_CATCH(f, [ x ])[1];;
BreakOnError := true;
return result;
end;
A warning: the CALL_WITH_CATCH function, and any other function with an ALL CAPS name, is undocumented and intended to only be used internally in GAP.
I have an integer : (using xcode for iPhone ) .
int wordCounter=1;
Later on, when i fill arrays with it-as a pointer,in a for loop, it somehow becomes 0 after it becomes a certain number . i have checked my program many times for bugs, and i realize that i dont even have a decrement on it anywhere . i do have wordCounter++.
Now i have seen that i have many lines like this,that after them it becomes 0 :
if(tempBinary[countWords-1][j] != tempBinary[countWords][j])
so i was thinking that countWords-1 decrement it down again and again, is that possible?
i dont have any other decrement or initialization on this variable in my whole program.
i COULD see that when the tempBinary defined as size 7, it initialize at 5, and if tempBinary is 5, it zeroing on 3 ..
is it possible that the array is overflow and is zeroing it? i dont think so..
whats wrong here ?
thanks .
EDIT (one of the problematic states)
int countWords=1;
int stabilityK=0;
tempBinary[0][0]= tempBinary[0][1]=tempBinary[0][2]=tempBinary[0][3]=tempBinary[0][4]=tempBinary[0][5]=tempBinary[0][6]=tempBinary[0][7]=1 ;
for(int k=0;k<numOfBuffers;k++)
{
NSLog(#"countwords:%d",countWords-1);
float *temp=getFFT(buffersRing[k],buffersRing[k][0]);
for(int j=0;j<wordSize;j++)
{
switch(state_on_signal)
{
case WAIT_FOR_SECOND_CHANGE:
//get new word
if(temp[goodBins[j]] > decisionLine[j])
tempBinary[countWords][j]=1;
else
tempBinary[countWords][j]=0;
if(tempBinary[countWords-1][j] != tempBinary[countWords][j])
newData=1;
NSLog(#"s1: countwords:%d",countWords-1);
if(j==wordSize-1)
{
NSLog(#"s2: countwords:%d",countWords-1);
NSLog(#"PRE TEMP:%d%d%d%d%d%d%d%d",tempBinary[countWords-1][0],tempBinary[countWords-1][1],tempBinary[countWords-1][2],tempBinary[countWords-1][3],tempBinary[countWords-1][4],tempBinary[countWords-1][5],tempBinary[countWords-1][6],tempBinary[countWords-1][7] );
NSLog(#"NEW TEMP-WAIT FOR SECOND CHANGE :%d%d%d%d%d%d%d%d",tempBinary[countWords][0],tempBinary[countWords][1],tempBinary[countWords][2],tempBinary[countWords][3],tempBinary[countWords][4],tempBinary[countWords][5],tempBinary[countWords][6],tempBinary[countWords][7] );
NSLog(#"s3: countwords:%d",countWords-1);
//TAKE NEW DATA
if(newData==1)
{
NSLog(#" TOOK new BINARY at current k:%d, so took data at: %d",k,(k+markedK)/2);
for(int s=0;s<wordSize;s++)
{
if( getFFT(buffersRing[(k+markedK)/2],buffersRing[(k+markedK)/2][0])[goodBins[s] ] >decisionLine[s] )
binary[countWords-1][s]= 1;
else
binary[countWords-1][s]= 0;
}
NSLog(#"s4: countwords:%d",countWords-1);
NSLog(#"BINARY%d: %d%d%d%d%d%d%d%d :%d",(countWords-1), binary[(countWords-1)][0], binary[(countWords-1)][1], binary[(countWords-1)][2], binary[(countWords-1)][3], binary[(countWords-1)][4], binary[(countWords-1)][5], binary[(countWords-1)][6], binary[(countWords-1)][7],[self getDecimal:binary[countWords-1]]);
countWords++;
markedK=k;
state_on_signal=WAIT_FOR_STABILITY;
}
newData=0;
}
break;
so i was thinking that countWords-1 decrement it down again and again,
is that possible?
No
Usually this happens when you misuse a pointer and write a value to the wrong address in memory.
For example: where and how is declared tempBinary ?
As it's not possible (at least for me) to see the problem just looking at your code I'd suggest to step through your code with the debugger and see when countWords gets changed. Here lies the problem (at least one of them).
I am basically trying to obtain the samples produced by an AUGraph using a GenericOutput Node and a call to AudioUnitRender. As a starting point for my program I used the MixerHost example by Apple and changed the outputNode as follows.
AudioComponentDescription iOUnitDescription;
iOUnitDescription.componentType = kAudioUnitType_Output;
iOUnitDescription.componentSubType = kAudioUnitSubType_GenericOutput;
iOUnitDescription.componentManufacturer = kAudioUnitManufacturer_Apple;
iOUnitDescription.componentFlags = 0;
iOUnitDescription.componentFlagsMask = 0;
Later when I want to obtain my samples, I call
AudioUnitRenderActionFlags ioActionFlags = kAudioOfflineUnitRenderAction_Render;
AudioTimeStamp inTimeStamp = {0};
inTimeStamp.mHostTime = mach_absolute_time();
inTimeStamp.mFlags = kAudioTimeStampSampleHostTimeValid;
result = AudioUnitRender (
ioUnit,
&ioActionFlags,
&inTimeStamp,
1,
1024,
ioData
);
which yields an
"-10877 / Invalid Element"
error. My assumption is, that the error comes from not setting the inTimeStamp.mSampleTime field correctly. To be honest, I have not found a way to find out the sample time other than AudioQueueDeviceGetCurrentTime, which I cannot use, since I do not use an AudioQueue. However changing the ioActionFlag to kAudioTimeStampHostTimeValid does not change the the error behaviour.
The error pertaining to the element (AKA 'bus') refers to the 4th argument (1) to your AudioUnitRender call. The Generic Output unit only has one element/bus: 0 which has an input, output and global scope. If you pass 0 to the call instead of 1 for the element #, that error should disappear.
I'm trying to use cvFindContours, which definitely seems like the way to go. I'm having a problem with getting the largest one. There is a function call cvContourArea, which suppose to get the area of a contour in a sequence. I'm having trouble with it.
int conNum = cvFindContours(outerbox, storage, &contours, sizeof(CvContour),CV_RETR_LIST,CV_CHAIN_APPROX_NONE,cvPoint(0, 0));
CvSeq* current_contour = contours;
double largestArea = 0;
CvSeq* largest_contour = NULL;
while (current_contour != NULL){
double area = fabs(cvContourArea(&storage,CV_WHOLE_SEQ, false));
if(area > largestArea){
largestArea = area;
largest_contour = current_contour;
}
current_contour = current_contour->h_next;
}
I tried replacing storage (in the cvContourArea) with contours, but same error keeps coming up no matter what:
OpenCV Error: Bad argument (Input array is not a valid matrix) in cvPointSeqFromMat, file /Volumes/ramdisk/opencv/OpenCV-2.2.0/modules/imgproc/src/utils.cpp, line 53
I googled and could hardly find example of cvContourArea that takes 3 arguments.. as if it's changed recently.. I want to loop thru the found contours and find the biggest one and after that draw it using the cvDrawContours method.. Thanks!
Try to change &storage to current_contour in the following statement.
Change
double area = fabs(cvContourArea(&storage,CV_WHOLE_SEQ, false));
to
double area = fabs(cvContourArea(current_contour,CV_WHOLE_SEQ, 0));