I've run into a really interesting runtime bug which generates a rogue stack overflow.
I've defined a structure as follows:
public enum EnumDataType { Raspberry, Orange, Pear, Apple };
public class DataRequest
{
public long DataSize
{
get { return 0; }
set { DataSize = value; }
}
public EnumDataType DataType
{
get { return EnumDataType.Apple; }
set { DataType = value; }
}
}
The following lines work perfectly:
DataRequest request = new DataRequest();
request.DataSize = 60;
However, when I step over the following line in code, it generates a stack overflow:
request.DataType = EnumDataType.Raspberry;
Of course, I can fix it by removing the defaults, or using auto get/set, but I need it to be both readable and writable, and return a default - any ideas?
Do not use a recursive function to generate or process the records and do not allocate the records on the stack. Recursion can be replaced by iteration, and a stack array can be replaced by std::vector. To avoid a stack overflow error, don't put so much data on the stack. Essentially: don't use local variables that are large arrays.
Underflow happens when we try to pop an item from an empty stack. Overflow happens when we try to push more items on a stack than it can hold. An error is a mistake that is probably unrecoverable. An exception is an error that can often be handled, so the program can recover.
The canary is overwritten if the buffer overflows. Further, the compiler identifies by comparing with known values that the stack is compromised and generates an error saying: stack smashing detected.
What Is Stack Overflow? - Errors, Exceptions & Causes Lonny was once a software programmer (video game industry). He now teaches psychology at King University. He has a bachelor's in IT and a PhD in psychology. Stack overflow in computer programming occurs when more items than a stack can hold are added.
public long DataSize { get { return 0; } set { DataSize = value; } }
You are constantly setting the value of DataSize
. You need to create a local variable and use that instead. e.g.
private long dataSize;
public long DataSize
{
get { return this.dataSize; }
set { this.dataSize = value; }
}
EDIT
I've written DataSize
but the same applies to DataType
As others have said, the stack overflow occurs because your property setter is just calling itself. It may be simpler to understand if you think of it as a method:
// This obviously recurses until it blows up
public void SetDataType(long value)
{
SetDataType(value);
}
As I understand it, you're trying to create normal properties but with a default value, right?
In that case, you need backing variables which are set by the setters - and the getters should return those variables, too. It's the variables which should get default values:
private long dataSize = 0;
public long DataSize {
get { return dataSize; }
set { dataSize = value; }
}
private EnumDataType dataType = EnumDataType.Apple;
public EnumDataType DataType {
get { return dataType; }
set { dataType = value; }
}
Alternatively, use automatic properties but set the defaults in your constructor:
public long DataSize { get; set; }
public EnumDataType DataType { get; set; }
public DataRequest()
{
DataSize = 0; // Not really required; default anyway
DataType = EnumDataType.Apple;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With