some doubts in the following code - visual-c++

have a look at the code below once and help me out by clarifying my doubts.
I have commented my doubts on each lines where i have doubts. Moreover, its a part of code from a huge one. so please ignore the variable declarations and all.
The whole code is working perfect and no errors while compiled.
double Graph::Dijkstra( path_t& path )
{
int* paths = new int[_size];
double min = dijkstra(paths); // **is a function call or not? bcz i didn't found any function in the code**
if(min < 0) { delete[] paths; return -1;}
int i = _size - 1;
while(i>=0)
{
path.push(i); // **when will the program come out of this while loop, i'm wondering how does it breaks?**
i=paths[i];
}
path.push(0);
delete[] paths;
return min;
}
Full coding is available here.

double min = dijkstra(paths); // **is a function call or not? bcz i didn't found any function in the code**
It almost certainly is. However, it could be a free function, member function, function invoked by a macro, or something else. Without seeing the rest of the code, we can only guess.
while(i>=0)
{
path.push(i); // **when will the program come out of this while loop, i'm wondering how does it breaks?**
i=paths[i];
}
The program will come out of the loop as a soon as i is less than zero. If I had to guess, I'd say the each node in the path contains a link to the previous node's index with the last node in a path returning -1 or some other negative number.

Related

Is it possible to sort a vector of string with std::sort(), based on a complex criteria?

I need to sort a std::vector<std::wstring> which contains folder names, in a such manner that the parent folder is always located after all its children, e.g:
C:\Main\App\QtGraphicalEffects\private
C:\Main\App\QtGraphicalEffects
C:\Main\App\Qt\labs\platform
C:\Main\App\Qt\labs
C:\Main\App\Qt
C:\Main\App
C:\Main\
To reach a such sorting I may use a Bubble Sort algorithm, as the following one:
void BubbleSortDirs(std::vector<std::wstring>& dirs)
{
bool swapped = false;
do
{
swapped = false;
for (std::size_t i = 0; i < dirs.size() - 1; ++i)
// swap positions if first dir is entirely contained in the second
if (dirs[i] != dirs[i + 1] && dirs[i + 1].find(dirs[i]) == 0)
{
std::swap(dirs[i], dirs[i + 1]);
swapped = true;
}
}
while (swapped);
}
This code works well, but I feel that a better solution should exist. So I tried to use the std::sort function in order to optimize my sorting, at least to provide a more elegant solution.
I tried the following implementation:
bool SortDirs(const std::wstring& first, const std::wstring& second)
{
// swap positions if first dir is entirely contained in the second
return (first == second || first.find(second) == 0);
}
...
std::sort(dirs.begin(), dirs.end(), SortDirs);
I expected that std::sort() would provide the same result as the BubbleSortDirs() function, but it wasn't the case and the result failed in several locations. At this point I strongly suspect that std::sort() isn't adapted for a complex sorting criteria like the one I'm trying to apply.
So my questions are:
What is the reason why my call to std::sort doesn't provide the expected result?
Is there a way to achieve the above described sorting using the std::sort() function?
If yes, what am I doing wrong?
If no, is the above BubbleSortDirs() function the best way to achieve a such sorting, or does it exist something better?
I finally resolved my issue this way:
std::sort(dirs.rbegin(), dirs.rend());

Function inside a package is slower than outside the package

I use Rcpp and RcppArmadillo and i have a "strange" problem. Lets say that i have function f1(). I include this function inside my package and run the command "R CMD INSTALL". After it's done i run a benchmark and i realise that f1 is slower about 100 microseconds inside the package than outside. So if a function wants 100ms to finish, in the package wants about 200+ms.
Code:
functions.cpp
vec f1(vec x){
vec F( x.size() );
for( int i = 0; i < x.size(); ++i ){
// do something
}
return F;
}
exportfunctions.cpp
vec f1(vec x);
RcppExport SEXP MyPackage_f1(SEXP xSEXP) {
BEGIN_RCPP
RObject __result;
RNGScope __rngScope;
traits::input_parameter< vec >::type x(xSEXP);
__result = wrap(f1(x));
return __result;
END_RCPP
}
exportfunctions.R
f1<- function(x) {
.Call( ' MyPackage_f1 ' , PACKAGE = ' MyPackage ', x )
}
An example of how my code is been written.
I believe the problem is that a function.R calls a function.cpp wich calls the final function. But why is this happening inside the package and not in sourceCpp. I can't understand the difference.
Briefly:
100ms is a non-issue. You are coming from R which is an interpreted environment
Calling a function involves several steps. Finding a function in a package involves some more.
See the documentation for .Call() to see how to minimize lookup.
See the documentation for NAMESPACE to set identifiers there too.
The latter two points should help close the gap between calling an ad-hoc function in the environment (which is cheaper) verses calling a function from the properly created infrastructure for doing so a.k.a. a package.

using a for each loop with pointers

First of I have 2 Classes in 2 files (both .h and .cpp files), Create.h and AI.h.
Create.h has this struct in it:
public:
struct Cell
{
//some stuff
vector<Cell*> neighbors;
State state;
};
Here is the enum class State (stored in the Create.h file):
enum class State : char
{
//some states like "empty"
};
Now in AI.cpp I have a function like this:
void AI::Function(Create::Cell cell)
{
for each (Create::Cell* var in cell.neighbors)
{
if (var->state == State::empty)
{
}
}
}
So basically I am trying to access each individual Cell which is stored in cell.neighbors with a for each so I can do some stuff to each one of them.
According to my debugger though it doesn't even reach the if (var->state == State::empty) part. Am I using the for each wrong?
EDIT: The neighbors vector has definitely elements in it
If you are compiling with optimizations enabled, then an empty if statement like that might be completely removed (it has no side-effects).
(Although, I think the debugger won't let you set a breakpoint on that line, if it were removed. So this is an easy test -- try to set a breakpoint on the if itself.)
it seems that the vector is empty. You can check this printing its size before the loop.
And I would like to answer some comments. This form of the for loop is MS VC++ language extension. It is not C++/CLI.

JNA - Use structure array as byref argument

I know parts of this issue is covered by some posts here and I have looked at them and tested some but with no luck.
I have this native method signature which should populate the provided CBadgeData structure array with results:
int elc_GetBadges(int nHandle, char* cErr, int* nRecCount, CBadgeData** arr)
The CBadgeData structure is implemented as follows:
package test.elcprog;
import java.util.Arrays;
import java.util.List;
import com.sun.jna.Pointer;
import com.sun.jna.Structure;
public class CBadgeData extends Structure{
public static class ByReference extends CBadgeData implements Structure.ByReference { }
public int nBadgeID, nTrigger, nExtraData;
public String cName;
public CBadgeData(Pointer pointer){
super(pointer);
}
public CBadgeData(){ }
public String ToString() {
return nBadgeID + "," + nTrigger + "," + nExtraData + "," + cName;
}
#Override
protected List getFieldOrder() {
String[] s = new String[]{"nBadgeID","nTrigger","nExtraData","cName"};
return Arrays.asList(s);
}
}
My last try to craft this argument and call the method looked like this:
CBadgeData.ByReference[] badges = new CBadgeData.ByReference[max_items];
new CBadgeData.ByReference().toArray(badges);
int ret = inst.elc_GetBadges(handle, err, recCount, badges);
It fails with segmentation error.
My Question is what Java type should be provided here as an argument for the native CBadgeData** in the call to elc_GetBadges?
EDIT -1-
Populating the array myself (with or without terminating null pointer) didn't work and caused further Seg crashes. I then used Pointer[] arg as technomage suggested:
Pointer[] pointers = new Pointer[max_items];
for(int i=0; i<max_items; i++){
pointers[i] = new CBadgeData.ByReference().getPointer();
}
int ret = inst.elc_GetBadges(handle, err, recCount, pointers);
This caused no error but seems to not make any changes to the returning struct which should have contain 4 items in this case:
int bid = new CBadgeData(pointers[i]).nBadgeID; // this returns null for all items
Using explicit read() / write() on the struct led to Seg crashes again (on the read):
Any idea what am I still missing here?
EDIT -2-
Interestingly enough - using the Memory.get directly, after calling the native method, gets the correct results:
Memory m= (Memory)pointers[0];
System.out.println("1st int: "+m.getInt(0)); // this gets 24289 which is 5ee1
System.out.println("2nd int: "+m.getInt(4)); // this gets 3
System.out.println("3rd int: "+m.getInt(8)); // this gets 255
System.out.println("String: "+m.getString(12)); // this gets "Badge[5EE1]" as supposed
But the read() still crashes. Any thoughts?
I'm inferring that CBadgeData** input is intended to be an array of pointer to CBadgeData.
As such, the Structure.ByReference tagging is correct.
Structure.toArray() is probably not appropriate here, or at least not necessary (it allocates a contiguous block of structs in memory). You can just populate your array with CBadgeData.ByReference instances.
Perhaps your callee is expecting a NULL pointer at the end of the array? I don't see another indicator of the array length to the callee.
CBadgeData.ByReference[] badges = new CBadgeData.ByReference[max_items+1];
for (int i=0;i < badges.length-1;i++) {
badges[i] = new CBadgeData.ByReference();
}
badges[badges.length-1] = null;
Pretty sure that works. If for whatever reason there's a bug handling Structure.ByReference[], I know that Pointer[] is reliable and will do the same thing.
EDIT
If you use Pointer[] instead of Structure.ByReference[] (please post a bug to the project site if Structure.ByReference[] does not work), you will have to manually call Structure.write/read before/after your native function call, since JNA will not know that the pointers reference structures that need to be synched with native memory. I'd bet, however, that the cause of your crashes when using Structure.ByReference[] was simply that JNA was automatically calling Structure.read() after the call and triggered the same error that you see when calling it explicitly.
If you get a segfault on read, it likely means that your structure fields aren't properly aligned or defined, or (less likely) that you have corrupt data that can't be read properly. To diagnose this, set jna.dump_memory=true and print out your struct after calling Structure.write() to see if the contents of the structure appear as you'd expect. It'd also help to post the native and JNA forms of your structure here, if possible.

Potentially uninitialized local variable used? Why?

When I write this code and compile with /W4
long r;
__try { r = 0; }
__finally { }
return r;
I get:
warning C4701: potentially uninitialized local variable 'r' used
Why does this happen?
The compiler can't be sure the code inside of the try block will successfully run. In this case it always will, but if there's additional code in the try block r = 0 may never execute. In that case r is uninitialized hence the error.
It's no different than if you said:
long r;
if(something) {
r = 0;
}
return r;
(where 'something' is pretty much anything other than a constant true value).
Because long r; creates r but it is not initialized; it is null.
So it warns you that the variable is not initialized. In certain cases it will cause Null Pointers.
Adding this as an answer as it is of more interest than in just a comment:
The error never appeared until a labeled-statement: was inserted before the variable. Remove the goto & associated label and there is no warning.
This might have something to do with how namespace pathing is setup with a similar warning C4702 generated on a line number before the insertion of a goto block. MVCE still to be generated if anyone is interested.

Resources