1

I have a big project which includes several source files and header files. to put some variables together, I have used struct. However, time to time I get SIGABRT error for various arrays in my project. I have checked out net a little, and I figured out that I think I have to turn them to the <vector>. If you guys have another ideas, I really like to hear them. This is the error event:

http://i.hizliresim.com/gnGDdR.png

Here is my structs and their source files: tools.h:

#ifndef _TOOLS_H_
#define _TOOLS_H_

void initialization(int,int,int);
int createGraph(int);
void orderDegree(int);
int nextTime(float lambda,int timeslots,int PU_number);

struct cognitiveRadio
{
    int **followed;
    double *priority;
    double *demand;
    int *degree;
    bool *assigned;
};

struct Graph
{
    int **adj;
    int *degree;
};
struct timeMatrix
{
    double **value;
};
#endif

I defined them in the tools.h and first I have used in the tools.cpp as globally:

cognitiveRadio myCR;
Graph myGraph;
timeMatrix myMatrix;

However, I need to use them in other sources files too. So, I added the following lines in each other source files:

extern struct Graph myGraph;
extern struct cognitiveRadio myCR;
extern struct timeMatrix myMatrix;

I allocated them like this: (this one is in tools.cpp)

myMatrix.value=new double*[PU_number];
for( i=0;i<PU_number;i++)
    myMatrix.value[i]=new double[time_slots];

There are also another arrays in project, like this:

void orderDegree(int CR_Number)
{
    int *degreeOrdered;
    degreeOrdered=new int[CR_Number];
....
}

Here are the other header files:

HyperHeuristic.h:

#ifndef _HYPERHURISTIC_H_
#define _HYPERHURISTIC_H_
#include "tools.h"
/*********Hyper-Heuristics*************/
double hyperheuristic(int ColumnIndex,int CR_Number,int PU_number,int hh,int accCriteria,int ts);
double simple_random(int ColumnIndex,int CR_Number,int PU_number,int ts);
double AICS(int ColumnIndex,int CR_Number,int PU_number,int ts);
double executeLLHorder(int ColumnIndex,int *LLHorder,int CR_Number,int PU_number,int ts);
/*********Low Level Heuristics***********/
int *largestDegree(int ColumnIndex,int CR_Number,int PU_number, Graph myGraph,int **CRs,int *PUs);
int *maxRadius(int ColumnIndex,int CR_Number,int PU_number, Graph myGraph,int **CRs,int *PUs);
int *maxDemand(int ColumnIndex,int CR_Number,int PU_number, Graph myGraph,int **CRs,int *PUs);
int *maxPriority(int ColumnIndex,int CR_Number,int PU_number, Graph myGraph,int **assignmentTable,int *availablePUs);
int *justRandom(int ColumnIndex,int CR_Number,int PU_number, Graph myGraph,int **CRs,int *PUs);
void print(double **arr);
struct ACO
{
    int *LLH;
    double deltatau;
};
struct AICStools
{
    double **probability;
    double **tau;
    double *roulette_wheel;
};

#endif // _HYPERHURISTIC_H_

fitness.h:

#ifndef _FITNESS_H_
#define _FITNESS_H_

double fitnessCalc(int**CRs,int CR_Number,int ColumnIndex,int PU_Number,int ts);
#endif

In main.cpp, I have this:

int time_slots=nextTime(1,number_of_packets,PU_number);
initialization(PU_number,CR_Number,time_slots);
for(int i=0;i<2;i++)
{
    double x=hyperheuristic(i,CR_Number,PU_number,hh,accCriteria,time_slots);
    cout<<"Fitness value of time("<<i<<"): "<<(double)x<<endl;
}

Well, as you can see it is highly complex. But simply, order of call for functions is like this:

  • main.cpp calls HyperHeuristic() from hyperheuristic.cpp you see above

  • hyperheuristic() calls AICS() in the same source file

  • AICS() calls `executeLLHorder()̀ in the same source file

  • executeLLHorder() calls some Low level heuristics which you can see them in the ̀̀hyperheuristic.h

  • then again, executeLLHorder() calls fitnesscalc() from ̀fitness.cpp

However, I told before, sometimes it works perfectly, but sometimes it returns SIGABRT error for various arrays in the project. There is not any certain array. It just does it. What is the best way to allocate these arrays? especially arrays that in the structs ?

1 Answers1

0

I think I have to turn them to the vector

Your code is error prone, and these days its generally recommended not to use naked new and delete. You should wrap your allocations in a vector<T>, unique_ptr<T>, or shared_ptr<T>.

For example this:

struct timeMatrix {
    double **value;
};

myMatrix.value=new double*[PU_number];
for( i=0;i<PU_number;i++)
    myMatrix.value[i]=new double[time_slots];

Could become this:

struct timeMatrix {
    std::vector< std::vector<double> > values;
};

myMatrix.values.resize(PU_number);

for(i = 0; i < PU_number; i++)
    myMatrix.values[i].resize(time_slots);

This:

void orderDegree(int CR_Number)
{
    int *degreeOrdered;
    degreeOrdered=new int[CR_Number];
....
}

Could become this:

void orderDegree(int CR_Number)
{
    std::unique_ptr<int[]> degreeOrdered;
    degreeOrdered.reset(new int[CR_Number]);
....
}

Once you've wrapped your allocations in objects with automatic storage duration, you'll be in a better position to find your bugs. For example, with vector<T> you will get failed assertions if you try to access an element that is out of range.

http://www.cplusplus.com/reference/vector/vector/ http://www.cplusplus.com/reference/memory/unique_ptr/ http://www.cplusplus.com/reference/memory/shared_ptr/

CuriousGeorge
  • 7,120
  • 6
  • 42
  • 74
  • Thank you very much. I am converting them step by step now. I'tell you result soon. –  Feb 07 '15 at 02:46
  • I have a question. I was passing some arrays to another function by calling them. But now I get error "cannot convert vector to int".. for example `double executeLLHorder(int ColumnIndex,int *LLHorder,int CR_Number,int PU_number,int ts); here the `*LLHorder`` is a vector now. What should I do now? –  Feb 07 '15 at 03:01
  • pass the vector by const reference. - executeLLHorder(int ColumnIndex, const vector &LLHorder, int CR_Number,int PU_number,int ts); – CuriousGeorge Feb 07 '15 at 03:04
  • I did exactly what you said. But now it gives these 3 errors: `‘vector’ does not name a type | ISO C++ forbids declaration of ‘parameter’ with no type [-fpermissive] | expected ‘,’ or ‘...’ before ‘<’ token|` b.t.w. `#include ` is there. –  Feb 07 '15 at 03:12
  • "#include " or use "std::vector" including the "std::" – CuriousGeorge Feb 07 '15 at 03:15
  • This is not the cause of your problem, but I can see you calling unique_ptr::release()... That will leak memory. You should call unique_ptr::reset() if you want to delete it, or simply let the unique_ptr go out of scope – CuriousGeorge Feb 07 '15 at 03:55
  • it's hard to tell you more without seeing your code. If you're ok with posting it, you can use http://pastebin.com/ – CuriousGeorge Feb 07 '15 at 03:57
  • are you sure you have removed every single malloc() and free()? or are you reading or writing past the end of an array? – CuriousGeorge Feb 07 '15 at 04:01
  • You may be writing past the end of an array, which will corrupt memory, and possibly cause your error. See this answer by Jonhoo: http://stackoverflow.com/questions/2987207/why-do-i-get-a-c-malloc-assertion-failure#answer-19365957 – CuriousGeorge Feb 07 '15 at 04:08
  • all arrays are removed. still same... same screen shot. I don't know what to do anymore... Thank you man. so much... –  Feb 07 '15 at 04:30
  • did you read Jonhoo's answer? How are you iterating over your arrays? finally, I read up on google, and some suggested that it was a problem with your compiler toolchain. It may be worth it to give your code a spin in visual studio or xcode if you have them. Also, one of those IDEs may give you more detailed information about the problem. – CuriousGeorge Feb 07 '15 at 04:34
  • I didn't read it all because as you suggested, I removed all of them. And I tried to run it in VS, Codeblocks, ubuntu terminal, windows 8 and windows 7. –  Feb 07 '15 at 04:42
  • "I removed all of them" -> you can still perform out of bounds writes to a vector(accidentally). IIRC, vector still uses malloc to allocate it's memory. If you have written over top of something important, that allocation could fail. – CuriousGeorge Feb 07 '15 at 05:32
  • well, good luck, I guess. If all else fails, you comment everything out until the problem goes away, then uncomment things one by one until you find the offending piece of code... or.. I've never tried it, but I've heard Valgrind may help -> http://valgrind.org/ – CuriousGeorge Feb 07 '15 at 05:35
  • I accept your answer but problem still goes on. By the way I like to ask that, I turned them to the vector but assignments still like arrays: `myVec[i][j]=x;` Is it right? Or do I have to use a `tempVec` as row vector and then put it into the original vector? Is there any difference? –  Feb 07 '15 at 10:15
  • What you're doing is fine, because vector::operator[] returns a reference to the element. In languages like C#, there are "value types", which could cause the problem you are suggesting. In C#, If you have a List of structs(value types in C#), you cannot modify the return value of List::operator[], because it returns by value, meaning it returns a copy of the struct. On the other hand, if you had a List of classes in C#(reference types), even though List returns by value, that value is a reference, so you can modify it. Hope this makes sense. – CuriousGeorge Feb 07 '15 at 15:25
  • Thank you buddy. I solved it step by step via valgrind. Problems were mostly about things u have mentioned already. –  Feb 07 '15 at 19:04