I am new to C++ and working with STL container at the moment.
I got a serious problem executing a nodeStack.push(startnode) - the compiler shows up a
Critical error detected c0000374
Followign code shows the function where the mentioned error occurs:
vector<int> Graph::iterativeDepthSearch(map<int, vector<int>> adjlist, int startnode) {
stack<int> nodeStack;
vector<int> visitList;
// Knotenbesuchsliste initialisieren
int* val = new int(adjlist.size());
for (int i = 0; i < (int) adjlist.size(); i++) {
val[i] = 0;
}
int cnt = 1;
nodeStack.push(startnode);
....
}
The error occurs in the line nodeStack.push(startnode);, startnode is initialized with 0.
try int* val = new int[adjlist.size()]; you are currently allocating a single int and initializing its value, not allocating an array of ints.
The stack structure is corrupting because it is next to your pointer in the memory stack.
nodeStack.push isn't really your problem. You are declaring int* val - a pointer to int, then initializing the integer at val with the size of the list. You really want
int *val = new int[adjlist.size()];
It's possible that you are using an x86 DLL; when I got this error in VS4.5, I changed my target platform to x86 and switched to .Net 4.0. That worked for me.
Related
When I run my program with valgrind it gives an invalid read and write of size 8 error. I have broke my head over this but I can't see what's going wrong.
The valgrind errors occur in the last and second last lines of this code:
void MLPerceptron::returnOutputActivation(vector<Feature> imageFeatures,vector<double>& outputActivation){
int train = 1;
for (unsigned int i = 0; i<imageFeatures.size();i++){
activations[0] = imageFeatures[i].content;
feedforward(train);
activationsToOutputProbabilities();
setMinActivation(outputActivation,activations[2]);
}
}
void MLPerceptron::setMinActivation(vector<double>& minOutputActivation,vector<double> currentActivation){
for(unsigned int i=0;i<currentActivation.size();i++){
if(minOutputActivation[i] > currentActivation[i])
minOutputActivation[i] = currentActivation[i];
}
}
The vectors are initialized in another function and then given to the function returnOutputActivations, this happens in a different file see here:
void MLPController:: createOutputProbabilitiesVectorTest(vector<vector<Feature> >& testSet){
unsigned int nOutputProbabilities = settings.mlpSettings.nOutputUnits;
vector<double> input;
input.reserve(nOutputProbabilities*nMLPs);
for(int j=0; j<nMLPs; j++){
vector<Feature>::const_iterator first = testSet[j].begin();
vector<Feature>::const_iterator last = testSet[j].begin()+numPatchesPerSquare[j];
vector<double> inputTemp = vector<double>(nOutputProbabilities, 10.0);
mlps[0][j].returnOutputActivation(vector<Feature>(first,last),inputTemp);
input.insert(input.end(),inputTemp.begin(),inputTemp.end());
}
Feature newFeat = new Feature(input);
newFeat.setLabelId(testSet[0][0].getLabelId());
inputTrainSecondLayerMLP.push_back(newFeat);
}
I know that there already a lot of posts about the valgrind error but it didn't help me to figure out what's going wrong.
I think
Feature newFeat = new Feature(input)
is the problem. This will allocate a new Feature on the heap, but you will lose its address and it will thus not be deleted. Use Feature* newFeat = new Feature(input) as per MikeCAT's suggestion.
I'm new to C++ (I usually work on Java), and I'm trying to convert a ::CORBA::LongSeq object to a long * in C++, in order to perform operations on it afterwards.
So basically, what I tried is to do that :
long * Sample (const ::CORBA::LongSeq& lKeys) {
long nbElts = lKeys.length();
long * lCles = NULL;
for(int iIndex = 0; iIndex < nbElts; iIndex++) {
lCles[iIndex] = (long) lFCKey[iIndex];
}
return lCles;
}
And what happens is that I can retrieve the length of lKeys (so it should be looking at the right location, as far as I can tell), but then I get an access violation exception when I enter inside the for loop.
0xC0000005: Access violation reading location 0xFFFFFFFFFFFFFFFF
I'm not sure of what I'm doing wrong though... Anyone has an idea ?
Here is one solution, and you don't get into the mess with pointers:
#include <vector>
std::vector<long> Sample (const ::CORBA::LongSeq& lKeys)
{
long nbElts = lKeys.length();
std::vector<long> lCles(nbElts);
for(int iIndex = 0; iIndex < nbElts; ++iIndex)
lCles[iIndex] = (long) lFCKey[iIndex];
return lCles;
}
This is guaranteed to work correctly, if the number of elements is correct.
Since you say you know Java, then a std::vector<long> would be the equivalent to a few of the Java containers that store sequences of values. For example, you can get the return value and call the vector's data() function to get you a long * that points to the vector's internal buffer.
But overall, get out of the pointer business (or try to limit their usage).
Edit: The comment stated to use CORBA::Long. So here it is:
std::vector<CORBA::Long> Sample (const ::CORBA::LongSeq& lKeys)
{
long nbElts = lKeys.length();
std::vector<CORBA::Long> lCles(nbElts);
for(int iIndex = 0; iIndex < nbElts; ++iIndex)
lCles[iIndex] = lFCKey[iIndex];
return lCles;
}
The difference between Java and C++ is that you have to manage your memory yourself (in most cases).
The error you get is that you try to assign things to an uninitialized variable (lCles), and returning a local variable. The local variable lCles which is stored on the stack will be "destroyed" once you leave the method.
One suggestion of how to do this could be something like this:
long* lCles = new long[lKeys.length()];
for(int iIndex = 0; iIndex < nbElts; iIndex++) {
lCles[iIndex] = (long) lFCKey[iIndex];
}
return lCles;
The important part in the method calling this code is to then release the memory held by this lCles by doing a
delete [] lCles; // or whatever the name of the variable is.
when done.
Like this:
long * l = Sample(lkeys);
// Do your stuff here
delete [] l;
(Using std::vector as suggested in another answer is actually preferred, since you don't have to do memory management by yourself.)
There are two things wrong here.
1) You attempt to use lCles before you have initialised it:
long * lCles = NULL;
..
lCles[iIndex]
This causes the access violation inside the for loop.
2) You return a pointer, lCles which is only declared locally:
return lCles;
This means that it goes out of scope when the function exits, and it then becomes invalid.
As stated above my program works in Debug and Release without debug (ctrl + F5) however does not work in simply Release.
Just to clarify I have already checked to see if I have some uninitialized variables and I haven't (to the best of my knowledge anyway but I have spent quite some time looking).
I believe to have localized the issue and what I have come across is, in my opinion, very bizarre. First I set up the break points as shown in the picture below:
Then I run the program in release. And instantly the top break point moves:
I found this extremely odd. Now note the number 6302 assigned to 'n'. This number is correct and what I hoped to pass through. Now watch as I continue through the program.
We are still in good shape but then it turns for the worst.
'n' changes to 1178521344, which messes up the rest of my code.
Would someone be able to shed some light on the situation, and even better, offer a solution.
Thanks,
Kevin
Here is the rest of the function if it helps:
NofArr = n;
const int NA = n;
const int NAless = n-1;
double k_0 = (2*PI) / wavelength;
double *E = new double[NAless]; // array to hold the off-diagonal entries
double *D = new double[NA]; // array to hold the diagonal entries on input and eigenvalues on output
int sizeofeach = 0;
trisolver Eigen;
int* start; int* end;
vector< vector<complex <double>> > thebreakup = BreakUp(refidx, posandwidth, start, end);
for(int j = 0; j < (int)thebreakup.size(); j++){
// load the diagonal entries to D
for(int i =0; i < (int)thebreakup[j].size(); i++){
D[i] = -((double)2.0/(dx*dx)) + (k_0*k_0*thebreakup[j][i].real()*thebreakup[j][i].real());
}
// load the off diagonal
for(int i = 0; i < (int)thebreakup[j].size(); i++){
E[i] = (double)1.0 / (dx*dx);
}
sizeofeach = (int)thebreakup[j].size();
double *arr1= new double[sizeofeach];
arr1 = Eigen.EigenSolve(E, D, sizeofeach, mode);
complex <double> tmp( PhaseAndAmp[j][1]*cos(PhaseAndAmp[j][0]), PhaseAndAmp[j][1]*sin(PhaseAndAmp[j][0]));
// rebuild the break up with the mode
for(int i = 0; i < (int)thebreakup[j].size(); i++){
thebreakup[j][i] = (complex<double>(arr1[i],0.0)) * tmp ;
}
delete []arr1;
}
vector<complex<double>> sol = rebuild(thebreakup, start, end);
delete [] E;
delete [] D;
delete [] start;
delete [] end;
return sol;
I'm writing this as an answer, because it's way harder to write as a comment.
What strikes me immediately is the array "arr1"
First you allocate new memory and store a pointer to it in the variable arr1
double *arr1= new double[sizeofeach];
Then, immediately, you overwrite the address.
arr1 = Eigen.EigenSolve(E, D, sizeofeach, mode);
Later, you delete something. Is it safe?
delete []arr1;
It's not the double array you allocated, but something eigensolve returned. Are you sure you have the right to delete it? Try removing the delete here. Also, fix the memory leak too, by removing allocation in the first line I gave.
What worries me even more is that the "this" pointer changes. There is some nasty problem somewhere. At this point, your program has already been corrupted. Look for the issue somewhere else. Valgrind would be a GREAT tool if you can try to compile under linux.
It seems that there is some sort of code optimization going on in your program. It is not always easy to debug optimized code step-by-step since the optimization may reorder instructions.
I cannot see why the fact that 'n' changes to an apparently uninitialized value would be the root cause of the problem, since 'n' is anyways no longer used in your function. Seems like the memory is simply been released as part of the optimization.
I have discovered my mistake. Earlier in the program I was comparing pointers, not what they were pointing at. A stupid mistake but one I wouldn't have spotted without a long debugging session. My boss explained that the information given at the bottom of Visual Studio whilst in release mode cannot be trusted. So to "debug" I had to use std::cout and check variables that way.
So here is the mistake in the code:
if(start > end){
int tmp = start[i];
start[i] = end[i];
end[i] = tmp;
}
Where start and end were defined earlier as:
int* start = new int[NofStacks];
int* end = new int[NofStacks];
And initialized.
Thanks to all those who helped and I feel I must apologise for the stupid error.
The Fix being:
if(start[i] > end[i]){
int tmp = start[i];
start[i] = end[i];
end[i] = tmp;
}
I have a chunk of code:
void split(std::vector<std::string> * v,const char* s,const char* x) {
size_t len = strlen(s);
size_t slen = strlen(x); //slen = Search Length
if(len==0||slen==0)
return;
v->clear();
char* f = new char[len];
memset(f,0,len);
int * counter =new int;
(*counter)=0;
for(unsigned int i = 0; i<len; i++) {
if(isNext((s+(i*sizeof(char*))),x)) {
f[i]=1;
counter++;
}
}
if((*counter)==0) {
delete [] f;
delete counter;
v->clear();
return;
}
...
However when I am debugging it with gdb (on cygwin) or the visual studio debugger I get this error (from the cygwin console)
(gdb) step
36 if(len==0||slen==0)
(gdb) step
38 v->clear();
(gdb) step
std::vector<std::string, std::allocator<std::string> >::clear (
this=0x60003a3e0)
at /usr/lib/gcc/x86_64-pc-cygwin/4.8.2/include/c++/bits/stl_vector.h:1126
1126 { _M_erase_at_end(this->_M_impl._M_start); }
(gdb)
No matter where I compile it I get the same error! When I check the values of all the variables within gdb everything is correct (values are exactly what they should be). The vector does work because I intialize it in main(), use it and then delete it and reallocate it (all without issue). Am I missing some big thing here? Googling and debugging for hours didn't seem to bring up anything. Any help is appreciated!
There's a lot here that can be simplified, but as far as major problems there is this:
int * counter =new int;
(*counter)=0;
counter++;
The counter++ is incrementing the pointer not the value pointed to. I don't see any reason why this needs to be a pointer and should probably be avoided as it just adds complexity to this.
What does isNext do? There definitely a lot you can do to simply this and when that's done it will likely reduce problems.
What are you passing to split? If the vector is uninitialized the call to ->clear() could cause an access violation.
I have the following code:
int **arr = new int*[5];
for(int i = 0; i < 5; ++i)
arr[i] = new int[];
for(int i = 0; i < 5; ++i)
delete [] arr[i];
delete [] arr;
Now it compiles and runs successfully, however if I remove the array size '5' from the first line the code compiles but crashes with run-time error on the last line. I have the following questions that I have failed to find answers in Straustrup's C++ book, in the internet etc.
Why the code crashes in the specified case ? (My guess is that delete [] fails to find the array size to be deleted and crashes.)
If it is not allowed to allocate multidimensional arrays without indicating the size why such errors are not caught by compiler at compile time ?
With the [5], you're getting an array of 5 int*s.
If you remove the [5], you're saying you want a pointer to a pointer to an int. So essentially, you have new int*[1].
Then you are indexing it with numbers from 0 to 4, which is out of bounds.