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!
Related
So, I have the following code where I have a class x on the heap and I return its value. Let's say that if res would be declared on the stack, it would cause a stack overflow. Then, in the code below, since I am returning the value stored on the heap, will it cause a stack overflow? Do I have to return a pointer to x?
x func ()
{
x* res = new x;
// code
return *res;
}
int main ()
{
x* s = new x;
*s = func();
}
Also, I know I didn't delete the string.
EDIT: Changed from std::string to class x.
Can a value returned by a function cause a stack overflow?
Return value can be stored on the stack. Anything that is stored on the stack can cause a stack overflow if it is larger than fits on the stack.
In an example call convention, the caller allocates the stack space for the return value, and parameters are stored after it, in which case if the return value overflows the stack, then that happens before the function is even called.
... will it cause a stack overflow?
Potentially, yes. Here is a demo: http://coliru.stacked-crooked.com/a/daca31b6551d1be5
Stack overflow is not guaranteed if there is optimisation involved which avoid creation of the temporary object. Same example with optimisation enabled: http://coliru.stacked-crooked.com/a/11fd38960fd62155
Do I have to return a pointer to x?
If sizeof of the type is very large, then you should avoid returning it by value just as much as you should avoid declaring variables with automatic storage, or creating temporary objects, or passing as value arguments.
In this example a std::unique_ptr would probably be a good choice.
To elaborate a bit on my comment. Normally this should not cause stack overflow if sizeof(X), where X is your type, is not extremely large - which it should not be in the well designed application.
However, you could play a bit with your example and check what will happen in case of large data structure:
// very bad 1MB structure
struct X
{
char data[1024*1024];
};
int main() {
std::cout << sizeof(X) << std::endl;
auto x = foo();
// data[0] is undefined, printing to prevent compiler from optimizing it out
std::cout << x.data[0] << std::endl;
return 0;
}
Now run it with valgrind and set the stacksize to less than 1MB:
valgrind --main-stacksize=1000000 --leak-check=full --log-file=vg.valgrind ./xxx
You might get the output similar to this:
Process terminating with default action of signal 11 (SIGSEGV)
Access not within mapped region at address 0x1FFEEFFB60
Stack overflow in thread #1: can't grow stack to 0x1ffeeff000
Note: the overflow is caused by the function call itself, not by storing the returned value, this example would be enough:
int main()
{
foo();
return 0;
}
however, gcc with -O1 or higher will optimize it out if foo does not have any side effects. You can compile with -O0 to see overflow in simplified example.
Simple improvement to struct X to avoid allocating big amount of data on the stack:
struct X
{
X(): data(1024*1024, 'x') {}
std::string data;
};
I wnat to use struct as a return value of fucntion but it doesn't work and i dont know why. Program crash when i run this program. I got RTE. What is wrong with this code :
#include <iostream>
using namespace std;
struct Tablica{
int T[201][201];
};
Tablica test(Tablica A, int m){
if(m==1)return A;
if(m%2 ==1){
return test(A, m-1);
}else{
cout <<" #1 m " << m<<endl;
Tablica B = test(A,m/2);
cout <<" #2 m " << m<<endl;
return B;
}
}
int main(){
Tablica T;
test(T,10);
}
Lets do the math: The structure is almost 160kB in size (201 * 201 * 4 (sizeof(int))), each call creates two of those instances on the stack, one for the argument A, one for the variable B, meaning each call uses around 320kB of stack. You have three calls, so that's 960kB. Plus the original variable T in the main function upping the stack size used to 1120kB, which is over the 1024kB default process stack size used on Windows. Leading to a stack overflow and your crash.
The absolute simplest solution? Make the argument to the function a constant reference, i.e.
Tablica test(const Tablica& A, int m)
The problem with this is that you still have at least once instance every call on the stack, the variable B, so that just gives you a few more recursive calls before running out of stack.
A more complex solution would be to use std::vector for the data in the structure, which puts the data on the heap and makes the structure several magnitudes smaller. This, together with the above solution to use a reference for the argument, is a more long-term solution, and will allow you quite a lot of recursive calls before running out of stack. It won't last forever though, the stack is a limited resource and sooner or later you will still run out.
The not recommended solution is to increase the stack size for the process, and that's only for when the last solution above hits the limit, but then you should start thinking about other and better designs to solve your problem before increasing the stack size.
"Process is terminated due to StackOverflowException" is the error I receive when I run the code below. If I change 63993 to 63992 or smaller there are no errors. I would like to initialize the structure to 100,000 or larger.
#include <Windows.h>
#include <vector>
using namespace std;
struct Point
{
double x;
double y;
};
int main()
{
Point dxF4struct[63993]; // if < 63992, runs fine, over, stack overflow
Point dxF4point;
vector<Point> dxF4storage;
for (int i = 0; i < 1000; i++) {
dxF4point.x = i; // arbitrary values
dxF4point.y = i;
dxF4storage.push_back(dxF4point);
}
for (int i = 0; i < dxF4storage.size(); i++) {
dxF4struct[i].x = dxF4storage.at(i).x;
dxF4struct[i].y = dxF4storage.at(i).y;
}
Sleep(2000);
return 0;
}
You are simply running out of stackspace - it's not infinite, so you have to take care not to run out.
Three obvious choices:
Use std::vector<Point>
Use a global variable.
Use dynamic allocation - e.g. Point *dxF4struct = new Point[64000]. Don't forget to call delete [] dxF4struct; at the end.
I listed the above in order that I think is preferable.
[Technically, before someone else points that out, yes, you can increase the stack, but that's really just moving the problem up a level somewhere else, and if you keep going at it and putting large structures on the stack, you will run out of stack eventually no matter how large you make the stack]
Increase the stack size. On Linux, you can use ulimit to query and set the stack size. On Windows, the stack size is part of the executable and can be set during compilation.
If you do not want to change the stack size, allocate the array on the heap using the new operator.
Well, you're getting a stack overflow, so the allocated stack is too small for this much data. You could probably tell your compiler to allocate more space for your executable, though just allocating it on the heap (std::vector, you're already using it) is what I would recommend.
Point dxF4struct[63993]; // if < 63992, runs fine, over, stack overflow
That line, you're allocating all your Point structs on the stack. I'm not sure the exact memory size of the stack but the default is around 1Mb. Since your struct is 16Bytes, and you're allocating 63393, you have 16bytes * 63393 > 1Mb, which causes a stackoverflow (funny posting aboot a stackoverflow on stack overflow...).
So you can either tell your environment to allocate more stack space, or allocate the object on the heap.
If you allocate your Point array on the heap, you should be able to allocate 100,000 easily (assuming this isn't running on some embedded proc with less than 1Mb of memory)
Point *dxF4struct = new Point[63993];
As a commenter wrote, it's important to know that if you "new" memory on the heap, it's your responsibility to "delete" the memory. Since this uses array new[], you need to use the corresponding array delete[] operator. Modern C++ has a smart pointer which will help with managing the lifetime of the array.
Stumbled upon this interview question somewhere,
In C,
Given a variable x, how do you find out if the space for that variable is allocated on the stack or heap?
(Is there any way to find it out programatically and not having to go through the symbol table, etc? And does finding if the space is allocated in stack or heap has any practical implications?)
No, not in general.
Do you know of gcc -fsplit-stack ?
It is up to the implementation to decide whether to allocate a contiguous stack or a stack where blocks are interleaved with heap blocks in memory. Good luck figuring out whether a block was allocated for the heap or the stack when the latter is split.
If you are working on an architecture that stores the stack on a larger address than the heap, you could compare the variable address with the bottom of the stack. Using the pthread threading API, this comparison would look like this:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <inttypes.h>
int is_stack(void *ptr)
{
pthread_t self = pthread_self();
pthread_attr_t attr;
void *stack;
size_t stacksize;
pthread_getattr_np(self, &attr);
pthread_attr_getstack(&attr, &stack, &stacksize);
return ((uintptr_t) ptr >= (uintptr_t) stack
&& (uintptr_t) ptr < (uintptr_t) stack + stacksize);
}
The test:
int main()
{
int x;
int *p1 = malloc(sizeof(int));
int *p2 = &x;
printf("%d %d\n", is_stack(p1), is_stack(p2));
return 0;
}
...prints 0 1, as expected.
The above code will not detect storage from stacks in other threads. To do that, the code would need to track all created threads.
This is NOT guaranteed by any standard BUT
on most platforms the stack grows down from highest address available, and heap grows up from the bottom if the most significant byte of the address is in the top half of the available memory space for your platform, and you haven't allocated gigabytes of memory, it's a pretty good bet it's on the stack.
#include <iostream>
#include <stdlib.h>
int main()
{
int x = 0;
int* y = new int;
unsigned int a1 = (int) &x;
unsigned int a2 = (int) y;
std::cout<<std::hex<<a1<<" "<<a2<<std::endl;
}
gives the output ffbff474 21600 on the machine I'm typing this.
It might be a trick question. Variables have either automatic or static storage duration[*]. You can fairly safely say that automatics are allocated "on the stack", at least assuming they aren't optimized into registers. It's not a requirement of the standard that there be "a stack", but a conforming C implementation must maintain a call stack and associate automatic variables with the levels of the call stack. So whatever the details of what it actually does, you can pretty much call that "the stack".
Variables with static storage duration generally inhabit one or more data sections. From the POV of the OS, data sections might be allocated from the heap before the program starts, but from the POV of the program they have no relation to the "free store".
You can tell the storage duration of a variable by examining its definition in the source -- if it's in function scope then it's automatic unless marked static. If it's not in function scope then it has static duration regardless of whether or not it is marked static (since the static keyword means something different there).
There is no portable way to tell the storage duration of a variable from its address, but particular implementations might provide ways to do it, or tools that you can use with greater or lesser reliability to take a guess.
Objects can also have dynamic storage duration (which generally is what "allocated on the heap" is intended to mean), but such objects are not variables, so that would be the trick if there is one.
[*] Or thread-local in C11 and C++11.
I don't think it has solutions. The code may adjust var's address by stack(heap) address scope, but it's would not be an exact way. At most, the code can only run in some certain platforms.
No it's not possible to determine that by memory location, the compiler would have to support it with isstack() to be portable.
One possible way to track memory allocation SPECIFICALY ON THE HEAP in C++ is overloading the new operator to keep tracking that for you. Then you know that if the memory is not allocated on the heap, it must be allocated on the stack.
#include <iostream>
#include <string>
// Variable to track how many allocations has been done.
static uint32_t s_alloc_count = 0;
void* operator new(size_t size){
s_alloc_count++;
std::cout << "Allocating " << size << " bytes\n";
return malloc(size);
}
Tracking the variable s_alloc_count you should be capable of see how many allocations on the heap has been done and have the size of these allocations printed on the console. Using debug tools like breakpoints, running the code "step-by-step" and console logging is one way to track where are these allocations. This is not an automated way but is a way to do that.
OBS: This tip should be only used for tests, avoid this type of code in production code.
I've been reading through some books, and when it comes to Class/Functions using Pointers/Dynamic Memory (or heap or w/e they call it) I start to get confused.
Does anyone have a simple....like easy example they can show, because the books im using are using overly complex examples (large classes or multiple functions) and it makes it hard to follow. Pointers have always been my weak point anyways but I understand BASIC pointers, just classes/functions using them is a little bit confusing.
Also.....when would you use them is another question.
Stack allocation:
char buffer[1000];
Here the 1000 must be a constant. Memory is automatically freed when buffer goes out of scope.
Heap Allocation:
int bufsz = 1000;
char* buffer = new char[bufsz];
//...
delete [] buffer;
Here bufsz can be a variable. Memory must be freed explicitly.
When to use heap:
You don't know how much space you will need at compile time.
You want the memory/object to persist beyond the current scope.
You need a large chunk of memory (stack space is more limited than heap space)
Your computer's RAM is a big pile of bytes ordered one after another, and each one of those bytes can be accesed independently by it's address: an integer number startig from zero, upwards. A pointer is just a variable to hold that address of a single place in memory.
Since the RAM is a big chunk of bytes, the CPU ussually divides that big pile of bytes on several chunks. The most important ones are:
Code
Heap
Stack
The Code chunk is where the Assembly code lies. The Heap is a big pool of bytes used to allocate:
Global variables
Dynamic data, via the new operation on C++, or malloc() on C.
The stack is the chunk of memory that gets used to store:
Local variables
Function parameters
Return values (return statement on C/C++).
The main difference between the Stack and Heap is the way it is used. While the Heap is a big pool of bytes, the Stack "grows" like a stack of dishes: you can't remove the dish on the bottom unless there are no more dishes on it's top.
That's how recursion is implemented: every time you call a function recursively, memory grows on the stack, allocating parameters, local variables and storing return values of the returning functions, one on top of the others just like the stack of dishes.
Data living on the Stack have different "Life Span" than the data living on the Heap. Once a function exits, the data on the local variables get lost.
But if you allocate data on the Heap, that data won't get lost util you explicitly free that data with the delete or free() operations.
A pointer is basically a variable that contains the memory address of another variable (or in other cases to a function, but lets focus on the first).
That means that if I declare int[] x = {5,32,82,45,-7,0,123,8}; that variable will be allocated to memory at a certain address, lets say it got allocated on address 0x00000100 through 0x0000011F however we could have a variable which indicates a certain memory address and we can use that to access it.
So, our array looks like this
Address Contents
0x00000100 1
0x00000104 32
0x00000108 82
0x0000010B 45
0x00000110 -7
0x00000114 0
0x00000118 123
0x0000011B 8
If, for example, we were to create a pointer to the start of the array we could do this: int* p = &x; imagine this pointer variable got created a memory address 0x00000120 that way the memory at that address would contain the memory location for the start of array x.
Address Contents
0x00000120 0x00000100
You could then access the contents at that address through your pointer by dereferencing the pointer so that int y = *p would result in y = 1. We can also move the pointer, if we were to do p += 3; the pointer would be moved 3 addresses forward (note, however, that it moves 3 times the size of the type of object it is pointing to, here I am making examples with a 32 bit system in which an int is 32 bits or 4 bytes long, therefore the address would move by 4 bytes for each increment or 12 bytes in total so the pointer would end up pointing to 0x0000010B), if we were to dereference p again by doing y = *p; then we'd end up having y = 45. This is just the beginning, you can do a lot of things with pointers.
One of the other major uses is to pass a pointer as a parameter to a function so that it can do operations on certain values in memory without having to copy all of them over or make changes that will persist outside of the function's scope.
Warning: Don't do this. This is why we have vectors.
If you wanted to create an array of data, and return if from a function, how would you do it?
Obviously, this does not work:
int [10] makeArray(int val)
{
int arr[10];
for(int i=0; i<10; ++i)
arr[i] = val;
return arr;
}
You cannot return an array from a function. We can use pointers to refer to the first element of an array, like this:
int * makeArray(int val)
{
int arr[10];
for(int i=0; i<10; ++i)
arr[i] = val;
return &(arr[0]); // Return the address of the first element.
// Not strictly necessary, but I don't want to confuse.
}
This, however, also fails. arr is a local variable, it goes on the stack. When the function returns, the data is no longer valid, and now you have a pointer pointing to invalid data.
What we need to do is declare an array that will survive even after the function exits. For that, we use keyword new which creates that array, and returns the address to us, which needs to be stored in a pointer.
int * makeArray(int val)
{
int * arr = new int[10];
for(int i=0; i<10; ++i)
arr[i] = val;
return arr;
}
Then you can call that function and use that array like this:
int * a = makeArray(7);
for(int i=0; i<10; ++i)
std::cout << a[i] << std::endl;
delete [] a; // never forget this. Obviously you wouldn't do it right
// away like this, but you need to do it sometime.
Using pointers with new also gives you the advantage that you can determine the size of the array at runtime, something you can't do with local static arrays(though you can in C):
int * makeArray(int size, int val)
{
int * arr = new int[size];
for(int i=0; i<size; ++i)
arr[i] = val;
return arr;
}
That used to be one of the primary purposes for pointers. But like I said at the top, we don't do that anymore. We use vector.
One of the last vestiges of pointers is not for dynamic arrays. The only time I ever use them, is in classes where I want one object to have access to another object, without giving it ownership of that object. So, Object A needs to know about Object B, but even when Object A is gone, that doesn't affect Object B. You can also use references for this, but not if you need to give Object A the option to change which object it has access to.
(not tested, just writing down. and keeping things intentionally primitive, as requested.)
int* oneInt = new int; // allocate
*oneInt = 10; // use: assign a value
cout << *oneInt << endl; // use: retrieve (and print) the value
delete oneInt; // free the memory
now an array of ints:
int* tenInts = new int[10]; // allocate (consecutive) memory for 10 ints
tenInts[0] = 4353; // use: assign a value to the first entry in the array.
tenInts[1] = 5756; // ditto for second entry
//... do more stuff with the ints
delete [] tenInts; // free the memory
now with classes/objects:
MyClass* object = new MyClass(); // allocate memory and call class constructor
object->memberFunction("test"); // call a member function of the object
delete object; // free the object, calling the destructor
Is that what you wanted? I hope it helps.
I think this is what you're asking about:
Basically C++ doesn't allow variable-sized arrays. Any array in C++ has to be given a very specific size. But you can use pointers to work around that. Consider the following code:
int *arry = new int[10];
That just created an array of ints with 10 elements, and is pretty much the same exact thing as this:
int arry[] = int[10];
The only difference is that each one will use a different set of syntax. However imagine trying to do this:
Class class:
{
public:
void initArry(int size);
private:
int arry[];
};
void class::initArry(int size)
{
arry = int[size]; // bad code
}
For whatever reason C++ was designed to not allow regular arrays to be assigned sizes that are determined at runtime. Instead they have to be assigned sizes upon being coded. However the other way to make an array in C++ - using pointers - does not have this problem:
Class class:
{
public:
~class();
void initArry(int size);
private:
int *arry;
};
class::~class()
{
delete []arry;
}
void class::initArry(int size)
{
arry = new int[size]; // good code
}
You have to do some memory cleanup in the second example, hence why I included the destructor, but by using pointers that way you can size the array at runtime (with a variable size). This is called a dynamic array, and it is said that memory here is allocated dynamically. The other kind is a static array.
As far as 2-dimensional arrays go, you can handle it kind of like this:
Class class:
{
public:
~class();
void initArrays(int size1, int size2);
private:
int **arry;
};
class::~class()
{
delete [] arry[0];
delete [] arry[1];
delete [] arry;
}
void class::initArrays(int size1, int size2)
{
arry = new int*[2];
arry[0] = new int[size1];
arry[1] = new int[size2];
}
Disclaimer though: I haven't done much with this language in a while, so I may be slightly incorrect on some of the syntax.