Segmentation fault in recursive function returning list - c++

I have a recursive function, that is returning a list of structs.
struct Neighbour_node{
int index;
double dist;
};
And here is the function:
list<Neighbour_node> findNewNeighbours(int original, int particle, int k){
Neighbour_node node;
list<Neighbour_node> neighbours;
list<Neighbour_node> temp_neighbours;
list<Neighbour_node>::iterator iterator;
if (k <= 0){
if (particle == -1){
node.index = -1;
node.dist = 1000.0;
}
else{
node.index = particle;
node.dist = glm::length(hair[original].position - hair[particle].position);
neighbours.push_back(node);
}
}
else {
for (unsigned int i = 0; i < hair[particle].neighbours.size(); i++){
temp_neighbours = findNewNeighbours(original,hair[particle].neighbours[i],k - 1);
temp_neighbours.sort(compareNeighbour_node);
neighbours.merge(temp_neighbours,compareNeighbour_node);
}
}
return neighbours;
}
Line:
temp_neighbours = findNewNeighbours(original,hair[particle].neighbours[i],k - 1);
causes segmentation fault and I am not sure why. I have seen examples with line similar to my erroneous one and it seems, it is not wrong. But those functions were not recursive, so I am guessing that this is where the problem is - besides, when k = 0 (only one call of a function - thus as if it wasn't recursive), then it doesn't crash. Can anyone, please, help me with this?
Thanks

Check the stack size in your os.
ulimit -s
I suggest that it is because of stack.
Becase the stack you need seems increase rapidly.
Show your "hair" for more detail for us to see.

Related

Error: Char 34: runtime error: addition of unsigned offset to 0x603000000070 overflowed to 0x60300000006c (stl_vector.h) (C++)

I have been trying to solve the sorted Squares leetcode problem (https://leetcode.com/explore/learn/card/fun-with-arrays/521/introduction/3240/), and I am mostly through it. However, I get the above error. Following is my code
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
int start = 0;
int end = nums.size()-1;
vector<int> final(nums.size());
int finalIdx = final.size()-1;
int sqr = 0;
while(start<=end){
if (abs(nums[start])<abs(nums[end])){
sqr = nums[end]*nums[end];
final[finalIdx] = sqr;
finalIdx--;
end--;
}
if (abs(nums[start])>abs(nums[end])){
sqr = nums[start]*nums[start];
final[finalIdx] = sqr;
finalIdx--;
start++;
}
else if(abs(nums[start])==abs(nums[end])){
sqr = nums[end]*nums[end];
final[finalIdx] = sqr;
finalIdx--;
final[finalIdx] = sqr;
finalIdx--;
start++;
end--;
}
return final;
}
}
};
The issue lies in my loop condition I believe. When I change the condition to start<end, I have no compile error, but the first element of the output array (final) is always 0, which I assume is by default. However, when I try to do start<=end in order to add a condition that handles the start==end case, I get the above error. I would like to understand why this is happening so I can rectify the issue. Thanks!
First, that's not a "compile error" ; it's a runtime error (and the error message reported says as much.
That said, the issue stems from the condition of start <= end landing on the = part of that condition. Eventually that is guaranteed to happen, save for one very specific set of circumstances:
start = (end-1)
abs(num[start]) == abs(num[end])
When that happens, your code will dump two values to the output vector, and both increment start and decrement end. The start and end indexes effectively swap values, the while condition is no longer true, and the loop will now cleanly exit.
In all other circumstances start and end will eventually land on the same index. When that happens your dual-push logic will dump the same value twice into the target vector, and that is where the issue manifests. There is only one value left to push (and start and end both reference it by index). Therefore you're going to push one more value into your target vector than you have space for, and the runtime exception ensues.
The fix is simple. Stop trying to be smart about short circuiting in three different conditions when in reality you only need one and a master-else. The computational requirements are the same no matter what, and in the end all you need is this:
class Solution
{
public:
std::vector<int> sortedSquares(std::vector<int> const &nums)
{
std::vector<int> final(nums.size());
int start = 0;
int end = nums.size()-1;
int finalIdx = final.size()-1;
while(start<=end)
{
if (abs(nums[end]) < abs(nums[start]))
{
final[finalIdx--] = nums[start]*nums[start];
++start;
}
else
{
final[finalIdx--] = nums[end]*nums[end];
--end;
}
}
return final;
}
};
If you really want all three conditions in your code, it is possible, but not warranted, and the special case circumstances don't justify doing it. Regardless, see below:
class Solution
{
public:
std::vector<int> sortedSquares(std::vector<int> const &nums)
{
std::vector<int> final(nums.size());
int start = 0;
int end = nums.size() - 1;
int finalIdx = final.size() - 1;
while (start <= end)
{
if (abs(nums[start]) < abs(nums[end]))
{
final[finalIdx--] = nums[end] * nums[end];
end--;
}
else if (abs(nums[end]) < abs(nums[start]))
{
final[finalIdx--] = nums[start] * nums[start];
start++;
}
else // !(a<b || b<0) implies (a == b)
{
int sqr = final[finalIdx--] = nums[end] * nums[end];
if (end != start)
{
final[finalIdx--] = sqr;
}
--end;
++start;
}
}
return final;
}
};

method giving app crashes due to segmentation fault in c++

this simple loop method is unable to run and an error arises "app crashed". when i checked this in an online compiler it gave 'segmentation fault(core dumped)'-
string studies(setMatter ch) {
string a = "LISTEN CAREFULLY!\n";
int i = 0;
while (i <= ch.a.quantity()) {
a += ch.a.getAns(i);
i++;
}
return a;
}
also see for reference of methods in the above code-
class Answer {
private:
vector<string> ch;
public:
void setAns(string ans) { ch.push_back(ans); }
string getAns(int num) { return (ch[num]); }
int quantity() { return ch.size(); }
};
am i accessing elements out of bond? but i dont know where as i every number starts from 0 in programming
Yes you are.
while(i<=ch.a.quantity()){
should be
while(i<ch.a.quantity()){
Valid vector indexes are zero up to the size of the vector minus one. That should be obvious, if the valid indexes started at zero and went to the size of the vector then there would be one more valid index than the size of the vector, which makes no sense.
Generally you use a for loop for this kind of task
for (int i = 0; i < ch.a.quantity(); i++) {
a += ch.a.getAns(i);
}
It's a little easier to read that way.

Trouble finding memory leak (deleting double pointer)

So I'm writing a program which uses a double pointer in some somewhat deep recursion, and I've got a huge memory leak which I can't find the source of. The way the program works is (and I'll post some sample code below) that there is a board object with a double pointer called "board" which is the real board (it's a connect 4 game) and another double pointer called "newBoard" which is what is used by a function called minimax() (outside of the Board class).
minimax() is recursive, stepping through each possible route the game could take, and since I don't want to edit the actual board at all, and I figured copying the entire "board" object thousands and thousands of times would be unncecessary, I thought that creating this "newBoard" pointer to copy the actual board would be the best option.
I have a function to delete newBoard, but it's not working like I'd like it to. Here are the relevant pieces of code:
minimax():
void Brain::minimax(Board board, int who, int currentCheck, int iter)
{
board.createNewBoard();
if (iter <= MAX_ITER)
{
for (int i = 0; i < w_; i++)
{
if (board.playMove(i, currentCheck))
{
if (winDetect(board, board.getDisc('c')))
{
if (iter == 0)
{
score[i] += 1000;
}
else
score[i] += (MAX_ITER - iter);
}
else if (winDetect(board, board.getDisc('p')))
{
if (iter == 1)
{
score[i] += 500;
}
else
score[i] -= (MAX_ITER - iter);
}
else if (!winDetect(board, board.getDisc('c')) && !winDetect(board, board.getDisc('p')))
{
if (currentCheck == board.getDisc('p'))
currentCheck = board.getDisc('c');
else if (currentCheck == board.getDisc('c'))
currentCheck = board.getDisc('p');
minimax(board, who, currentCheck, iter + 1);
}
}
}
}
}
createNewBoard():
void Board::createNewBoard()
{
newBoard = new int*[h_];
for (int i = 0; i < h_; i++)
newBoard[i] = new int[w_];
}
NB_delete():
void Board::NB_delete()
{
for (int i = 0; i < w_; i++)
delete[] newBoard[i];
delete[] newBoard;
}
I think that's all the relevant code, but if you think there might be more, let me know and I'll include it! Thanks in advance for any help.
EDIT: SOLVED
I had simply forgotten to call my NB_delete() function. Calling it fixed the program!
As far as I can see, newBoard is a member of class Board. Now minimax is called recursively and so is CreateNewBoard. That means: In CreateNewBoard you are overwriting newBoard in each successive recursive call! That's probably your memory leak.
If CreateNewBoard is to be called recursively, you need a separate instance of newBoard for each level of recursion. Or is newBoard a 2D array for that very reason and the h_ index denotes recursion depth? In that case you should not create a new instance of newBoard in iteration 2 ... h_.

Segmentation Error C++

I am fairly new to the C++ language and I am trying to write a recursive method to traverse a tree. I have a traverse method but there is one line of code that causes a segmentation fault. I have tested this by commenting and uncommenting the line, compiling and executing. I have researched why segmentation errors are caused and do not see why any of what I am doing is causing a problem with the memory. Can someone give me advice about what I am doing wrong?
map<int, Node> theNodes;
void initialize()
{
// first we read the data
while (inStream.hasNext())
{
string nextLine = inStream.nextLine();
Node newNode = Node(nextLine);
this->theNodes[newNode.getSequence()] = newNode;
}
}
Code for getDownLinks() and getSequence
vector<int> downLinks;
int sequence;
vector<int> Node::getDownLinks() const
{
return this->downLinks; //
}
int Node::getSequence() const
{
return this->sequence;
}
Traversal Class Code
int totalPayoff;
Node headNode;
int Traversal::traverse()
{
Node headNode = theNodes[0];
std::vector<int> downLinks = headNode.getDownLinks();
for(int i = 0; i < downLinks.size(); i++)
{
int a = 0;
Node currentNode = theNodes[downLinks[i]];
traverseInner(a, currentNode);
}
return this->totalPayoff;
}
Here is the traverseInner function
int Traversal::traverseInner(int& level, Node& node)
{
std::vector<int> nodeDownLinks = node.getDownLinks();
if(nodeDownLinks.size() == 0)
{
totalPayoff = totalPayoff + node.getPayoff();
return 0;
}
for(int i = 0; i < nodeDownLinks.size(); i++)
{
int a = 0;
Node currentNode = theNodes[nodeDownLinks[i]]; <-- This causes segmentation error.
traverseInner(a, currentNode);
}
return totalPayoff;
}
Any variables that are not declared here are declared in the header file. The code compiles fine.
I'd also like to mention that I have written this code in many different ways and through my observations have come to the conclusion that any variable that is trying to be accessed in the braces of a nested statement cannot be accessed by the memory. Even the int a variable that is declared right above the problem statement and even hard coded data which is supposed to be there such as nodeDownLinks. If I try to print out through standard output the size of the vector inside one of the nested statements, I also get a segmentation error.
Probably the value inside "nodeDownLinks[i]" it is not initialized, having a memory random value, then you are trying to access this position in the
"theNodes" array and gives to you the segmentation fault.
Please, be sure the values inside "nodeDownLinks" are initialized.
99% it crashes because theNodes has less size, then nodeDownLinks[i] contains index. So nodeDownLinks[i] contains wrong index, u'd better check it and print what goes wrong this way:
int a = 0;
int link = nodeDownLinks[i];
if (theNodes.size() <= link)
std::err << "Wrong link " << link << " in Node" << std::endl;
else
traverseInner(a, theNodes[link]);
It shouldnt crash and you can find wrong index in nodeDownLink easily!

sometimes getting a segmentation fault (core dumped)

my program will sometimes run okay but sometimes it crashes in the middle of running with a segmentation fault. and the fault will come at different times each time i run the program. i debugged with gdb and found that the problem is in this function
int chooseLink(int &h, vector<Edge> &link) {
double r = 1.0*rand() / RAND_MAX;
if (link[link[h].l_ID].q == link[link[h].r_ID].q) { // this is where the error occurs
if (r<0.5)
return link[h].l_ID;
return link[h].r_ID;
}
else {
if (r < link[link[h].l_ID].q / (link[link[h].l_ID].q + link[link[h].r_ID].q))
return link[h].l_ID;
return link[h].r_ID;
}
}
my program involves calling this function millions of times. can anyone suggest what the problem may be? I'm pretty sure the vector 'link' is not going beyond its capacity. this is my first time posting a problem, so sorry if I haven't provided enough information
update
someone asked why i'm passing h by reference. i thought that passing by reference is better than passing by value because it saves space and the program will run faster. is that not correct?
someone asked for the edge class, so here it is
class Edge {
public:
int ID; // ID of edge
bool type; // true for constant, false for variable
double q; // quantity on the edge
int l_ID = 0; // ID of left edge (equals 0 if doesn't exist)
int r_ID = 0; // ID of right edge
void assignType(double &p) {
if (p == 0.5)
type = false;
else
type = true;
}
};
i added a try-catch block to the function so it looks like this:
int chooseLink(int &h, vector<Edge> &link) {
try {
if (h<0 || h>=link.size() ) {
throw h;
}
} catch(...) {
cout << "ERROR: h = " << h << endl;
}
double r = 1.0*rand() / RAND_MAX;
if (link[link[h].l_ID].q == link[link[h].r_ID].q) { // this is where the error occurs
if (r<0.5)
return link[h].l_ID;
return link[h].r_ID;
}
else {
if (r < link[link[h].l_ID].q / (link[link[h].l_ID].q + link[link[h].r_ID].q))
return link[h].l_ID;
return link[h].r_ID;
}
}
and now i don't get the segmentation fault at all. Also, the program runs fine without ever throwing an exception. what's going on? when i remove this try-catch block, i get the segfault again. i don't understand it
The first suggestion is always to boundary or range check your parameters:
int chooseLink(int h, vector<Edge> &link)
{
const unsigned int container_size = link.size();
// Check index for range.
if ((h < 0) || (h >= container.size)
{
// Report error here.
}
else
{
// More checking.
const int left_id = link[h].l_ID;
const int right_id = link[h].r_ID;
if ((left_id < 0) || (left_id >= container.size))
{
// Perform error handling
}
if ((right_id < 0) || (right_id >= container_size))
{
// Perform error handling
}
// remember to use 'const' for items that won't change.
const double r = 1.0*rand() / RAND_MAX;
if (link[left_id].q == link[right_id].q)
{
// ALWAYS use braces, even for single statements.
if (r<0.5)
{
return left_id;
}
return right_id;
}
else
{
if (r < link[left_id].q / (link[left_id].q + link[right_id].q))
{
return left_id;
}
return right_id;
}
// What does it return here?
}
}
When in doubt, range check your variables.
Also, check your logic so that all paths of execution return a value.