segmentation fault when function called repeatedly [duplicate] - c++

This question already has answers here:
Stack overflow caused by recursive function
(6 answers)
Closed 6 years ago.
I am trying to run this code which for some reason crashes during execution with "Segmentation fault (core dumped)" error.When i ran this in Code::Blocks debugging mode,call stack showed me a different address for pointer after after some 130000 iterations.
#include <iostream>
using namespace std;
long long counter = 0;
void test(int* ptr)
{
cout << ptr[0];
if (counter == 10000000)
return;
counter++;
test(ptr);
}
int main()
{
int arr[2];
arr[0] = 10;
arr[1] = 20;
test(&(arr[0]));
return 0;
}

(Assuming a typical stack based system) Part of the memory of a process is is designated as an execution stack. Each function call will create a frame on the stack. This frame will contain the local variables and also possibly some implementation details such as the address of the frame of the caller.
Since every function call creates a new frame on the stack, it follows that every nested function call increase the height of the stack. The stack space is not infinite. There is a platform specific limit. If you try to put too many frames on the stack, the stack will overflow. This is what happened with your program.
Solution: Do not write functions that make a huge number of recursive calls. Avoid recursive calls, when they are not necessary. For example, your recursion can be replaced by an iterative loop structure:
void test(int* ptr) {
while(counter++ != 10000000)
cout << ptr[0];
}

Related

Is this an example of stack overflow in c++?

Learning pointers for the first time. So ptr is being assigned n, n1 and finally n2 but n and n1 were never deleted. Hope that makes sense.
#include <iostream>
using namespace std;
int main() {
int n = 5;
int n1 = 7;
int n2 = 8;
int *ptr;
ptr = &n;
ptr = &n1;
ptr = &n2;
cout << ptr << endl;
cout << *ptr << endl;
return 0;
}
The stack is generally a (relatively) small, fixed sized, area of memory allocated to each thread in your application. The stack memory used by a function is automatically released at the end of that function.
A stack overflow is when your program runs out of stack memory. This generally occurs for two reasons:
A large object is created on the stack, e.g. an array of 1,000,000 ints might use up 4mb of stack memory but on Windows the default stack size is usually 1mb so your program would encounter a stack overflow when the array is created.
Too many levels of function calls occur (e.g. infinite recursion). Each time you call a function an amount of stack memory is used to store the variables of that function along with parameters, return addresses etc. Depending on the amount of memory used by each function, the number of nested function calls you can do without causing a stack overflow will vary. E.g. if you create large arrays on the stack you'll be able to do far fewer levels of recursion than if each function just has a few integer variables.
Neither scenario is occurring in your code, you're creating 4 variables on the stack and assigning values to them. The behaviour is well defined and the memory will be automatically released at the end of main.
OKAY. Firstly, you did not assign the pointer ptr to &n, &n1 and &n2. You were simply overriding the assignments so at the end of the code, ptr was only assigned to &n2.
Secondly, MEMORY OVERFLOW occurs when there is a memory leak and this happens when you use new keyword to allocate memory and do not use delete to deallocate it.
#include<iostream>
using namespace std;
int main()
{
int* pointer;
pointer=new int;
*pointer=24;
cout<<*pointer;
delete pointer;
return 0;
}
Omitting the delete pointer; in this case would be an example of a memory overflow.
However, stack overflow is a different thing and it does not apply here.
I hope this helps!

Increasing stack size only for specific executable [duplicate]

This question already has answers here:
Change stack size for a C++ application in Linux during compilation with GNU compiler
(5 answers)
Closed 5 years ago.
WRT my question: Code execution breaking during recursion
I don't want to increase the stack size for every application running in my account. Just one C++ executable.
What is the way to do it?
If you really need huge amount of stack space you can make use of Boost Context and temporarily allocate a custom amount of stack space. This works on a per-thread level so it might not answer your question. However, as already said in comments, you should probably improve your algorithm as increasing stack size is hardly ever needed.
#include <boost/context/fixedsize_stack.hpp>
#include <boost/context/continuation.hpp>
void recurse(int depth)
{
std::cout << depth << std::endl;
recurse(depth + 1); // infinite recursion to test how far you can go
std::cout << depth << std::endl; // just to avoid tail recursion optimization.
}
int main(int argc, char* argv[])
{
namespace ctx = boost::context;
ctx::fixedsize_stack my_stack(100 * 1024 * 1024); // adjust stack size for your needs
ctx::continuation source =
ctx::callcc(std::allocator_arg, my_stack, [](ctx::continuation&& sink) {
// everything in here runs within a context with your custom stack.
recurse(1);
return std::move(sink);
});
// This starts the context and executes the lambda above.
source = source.resume();
return 0;
}
On Linux using GCC or Clang you could also replace fixedsize_stack with segmented_stack, which automatically grows until you run out of memory.
Boost Context is portable among most major platforms.

C++ Stack vs Heap and Pointers [duplicate]

This question already has answers here:
Can a local variable's memory be accessed outside its scope?
(20 answers)
Closed 7 years ago.
So I'm learning C++ (coming from a Java background). I thought I understood how memory works on a high level (stack vs heap and pointers). To experiment, I wrote the following two toy functions:
int* pntrToHeap(int val) {
return new int(val);
}
and
int* pntrToStack(int val) {
return &val;
}
At first I thought pntrToStack just wouldn't work, because the local variable val is on the stack which is "deleted" after the function exits. But after the following code worked without errors (with 1 warning, however), I reconsidered:
int main()
{
int val1 = *pntrToHeap(3);
int val2 = *pntrToStack(4);
cout << val1 << endl;
cout << val2 << endl;
return 0;
}
Both 3 and 4 printed to the screen. It seems as though the stack isn't actually deleted, but the CPU just loses the ability to access local variables on it -- is this correct? If so, in a case like this, which function should we prefer?
Lastly, since val1 is a local variable of main, is pntToHeap creating a memory leak since I can't delete the value it created on the heap?
I know these concepts have been asked about before, but I couldn't quite find the answers. Thanks!
Definitely the first one! If you want something to live after the stack frame expires you should heap allocate it.
And yes, the value pointed to by the pointer returned from pntrToStack will be overwritten the next time you allocate a new stack frame ie. call a function. When you exit out of a scope the memory is not erased. It is merely marked as being free to allocate.

Stack Overflow error in recursive C++ function [duplicate]

This question already has answers here:
Does C++ limit recursion depth?
(6 answers)
Closed 9 years ago.
#include<iostream>
using namespace std;
int f()
{
static int count=0;
count++;
if (count>=5000)
return count;
return f();
}
int main ()
{
cout<<f();
return 0;
}
this function overflows the stack after the value of count exceeds 4800 can anybody tell how to resolve this issue ?
Don't use recursion - use a regular loop. Every time you call your f() method, you will occupy few words on the stack, and you will overflow it at some point.
Usually, there's way to increase stack size (depending on your system and/or compiler), but I don't want to recommend that (especially because it will overflow again, just with the value of count bigger than 4800).
Or just int f(){ return 5000; } would do.
Assuming you want to run recursively, you could turn off debug mode, then you'll succeed (as Visual Studio adds extra stuff on the stack to detect if you "clobber" the stack [it's how it can say "The stack around variable x was overwritten" or whatever the exact message is].
However, relying on being able to do LARGE number of calls recursively is a bad plan in general - at some point or another, it will still fall over. Whether that is 5000, 50000 or 500000 is just a matter of "how much stack-space does this function take". I'd say anything that doesn't have a natural limit of around 100 levels of recursion is a case of "you are solving the problem the wrong way". If you do have such large recursion levels, it's better to use a software stack (e.g. std::stack in C++), and save the crrent state on that stack, and restore it, using the software inside the function.
Running out of stackspace is one of the worst possible runtime problems, because there is really nothing you can do - there may be things you can do to print an error message or some such, but there is really no way to "give the process some more stackspace and continue". When a process runs out of memory or something similar, you can say "Ok, I won't allocate that, and give the user an nice error message saying 'I can't do this', and the nicely save the current state and exit, for example."
[And yes, you can increase the stack-size of your application, but that really should only be done as a true last resort, and only when you fully understand WHY you need such large stack - it's very often something else you're doing wrong if you need a bigger stack].
I'm assuming this is for an academic exercise to learn about recursion. (If it is not, please don't use recursion for this!)
A better way to write your function:
#include <iostream>
int f(int i)
{
if (i >= 5000)
{
return i;
}
else
{
return f(i + 1);
}
}
int f_alt1()
{
return 5000;
}
int f_alt2()
{
int i = 0;
for (; i <= 5000; ++i);
return i;
}
int main()
{
std::cout << f(0) << std::endl;
return 0;
}
This will still eat up far more runtime resources than returning the constant or incrementing in a loop, and you will need to increase your stack size if you increase the desired constant to a significantly larger number.

theory and problems on memory usage [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What is a stack overflow error?
look the code below.
#include <iostream>
using namespace std;
void leave(double as){
cout<<as;
leave(as);
}
int main(){
double x=1234.5;
leave(x);
cout<<"hellow";
}
When this code executes their is no way to stop. it should print the value x over and over again. But practically, this works for about 20 secs and close automatically. It doesn't print the line hellow. What is the reason for it? In windows task manager I can realize that the memory used with the application will increase. but I have allocated memory for x within the main function only, so will the function allocate memory for x over and over again. Is this type of situation called a memory leak? if its so what lines should be added to prevent it?
If I change the code as below it shows the word hellow without going through the function over and over again:
void leave(){
leave();
}
int main(){
leave();
cout<<"hellow";
}
How to explain these situations?
Every call to leave() results in adding a little information to the stack. When you call it recursively, the stack grows until it runs out of space, and the operating system terminates the application. In the second example, presumably the compiler optimized out the function that did nothing.