When I put the list on the stack instead of the heap, i.e. change the
declaration of history to
1
std::list<std::string>History;
(and change the rest accordingly), the code crashes before printing the
first line. It also happens, when I declare history outside of the
function.
Development environment is CodeSourcery on Linux, if necessary I can
post the whole Eclipse project.
Thanks for thinking!
T
Hello,
there is to low stack memory for the list "History". At program
execution you get a stack overflow error. But you can not see it.
You should place lists always at the heap.
CU,
Hase
Why is that? std::list is just a doubly linked list, so the object
itself should only contain two pointers (to the first and last element),
am maybe some size info.
If put on stack, the elements themselves are put on heap, too, or am I
wrong?
I don't quite see the reason for the crash...
Hello Simon,
you declare
std::list<std::string> History; // List of strings. Not a list of
pointers to strings. Maybe i am wrong?
...
std::string CurrentLine(Line); // local string at the stack; not a the
stack
...
History.push_back(CurrentLine); // Put the string to the list
// My opion: the string is copied to
the list
Posible solutions:
1. Make a list of strings
2. Declare the string (buffer) at the heap.
char *pCurrentLine = new char[255];
cu
Hello Hase,
I agree that I strain the stack a bit, but out of the 64k RAM in the
STM32, I have less than 8k for .data and .bss sections. The remaining
56k are used for heap and stack. The initial stack pointer is set to the
end of RAM and the heap grows upwards from the end of the .bss section
(by means of the library function _sbrk).
So the RAM should be available to either stack or heap.
But I got some points for research from your second post, so I will do
some experiments with stack vs. heap variables and keep you updated.
Bye,
Thomas
Hello Hase,
I'm still not really sure about it. Yes, of course it's a list of
strings, and not a list of pointers to strings. But let's have a look at
what a list does: At the beginning, it's empty. So what is put on the
stack? I think, really just a small structure containing two pointers,
both pointing to NULL (or something like that).
Now, push_back() adds an element, a.e. a string to it. So, what happens?
I'm quite sure, a structure containing a string and a "next" pointer is
created on the heap. No matter if the list itself is put on the stack or
on the heap.
What you put on the stack or on the heap is just the "initial structure"
containing the "entry points", a.e. the pointers to the first and the
last element in the list.
Am I wrong?
I forgot:
You wrote:
> std::string CurrentLine(Line); // local string at the stack; not a the>stack>...> History.push_back(CurrentLine); // Put the string to the list
// My opion: the string is copied to
Yes, that's what happens, I think. The string is put on the stack first,
than, by push_back, a new element is created on the heap, including a
string object, which is crated using a copy constructor taking
CurrentLine as the argument.
So, I don't much stack usage here.
Hello,
why do you think that the string is allocated at the heap?
The string is allocated at the local stack and the list is allocated at
the local stack.
Please use a complier at a pc and check it.
CU
Still me, but now logged in:
The list is allocated on the stack, as you say. But what exactly IS a
"list object", when it's allocated? It's an object containing only a
"first" and a "last" pointer. Do you agree?
Then, here:
std::string CurrentLine(Line);
a string object is allocated at the stack, as you say. (btw: Depending
on the implementation, this means, that on the stack, there is more or
less only a pointer, and on the heap(!!), the real data is allocated.
But as I said, this depends on the implementation of std::string. Some
implementations I've seen, put small strings completely on the stack,
and larger ones on the heap. But let us assume now, that the string is
allocated entierly on the stack.)
Now let's look at this line:
pHistory->push_back(CurrentLine);
You think, that the object CurrentLine is appended to the list, but
that's not true. What really happens, is as follows:
The list object (which, as you say, is located on the stack) allocates a
"list item" on the heap. This list item has room for:
-a "next" pointer
-a "previous" pointer
-a string object
Then, CurrentLine is copied into this "list item" using a copy
constructor.
Have a look at this:
http://www.cplusplus.com/reference/stl/list/push_back/
Could you explain, how a list object could ever push_back() items on the
stack? That's impossible! push_back has its own stack frame, which is
"cleaned up" (by setting the SP) just after exiting. So, the item would
be "deleted" (a.e is not accessible any more) as well, as soon as
push_back() ends.
Greets
Simon
Hey guys,
interesting discussion.
I tend to agree to Simon, mainly because I cant imagine a way to
'allocate' something on the stack while a function runs. Maybe its
different with arm architecture, but with traditional (x86)
architectures, the stack layout (aka stack frame) is fixed at function
entry. So the only place to allocate something dynamically is the heap.
Which brings me back to my original question. I have some 56k from the
end of the bss section to the end of the RAM, which are shared by the
heap (growing upward) and the stack (growing downward). So how come, it
is enough, when I explicitly allocate on the heap, and it fails, when I
automatically allocate (parts of the objects) on the stack?
Greetings,
Tommi
Thomas H. wrote:> Maybe its> different with arm architecture,
no, this is a principle common to all architectures. So, the items are
definitively allocated on the heap.
>Which brings me back to my original question.
I don't quite see where the problem could be. But have you tried
stepping through the code to find out, what really makes the proc crash?
Simon wrote:
>But have you tried>stepping through the code to find out, what really makes the proc crash?
I dont have a debugger for my hardware, so I can't do that.
I will work on my debug options, but for now one observation:
vector behaves the same as list, but deque works as expected.
Thank you for sharing your thoughts, I will go on to make more hardware
peripherals (e.g. the debug port) available on my 'bare metal' system.
Tommi