`Variable 'size' is 10 in this example. If I were to hardcode 10 in place of 'int(size)' the overrun warning goes away. Any suggestions/reasoning why this is occurring? I want to allocate 80 bytes for my pointer, each of the allocated values being a timestep from the given timespan.
Thank you!
int main() {
const double h = 0.1;
const double tspan[2] = { 0.0, 1.0 };
const double size =round(tspan[1] / h);
double *ptr = (double*)malloc(int(size) * sizeof(double));
if (!ptr) {
cout << "Memory Allocation Failed";
exit(1);
}
double j = 0;
for (int i = 0; i < size; i ) {
ptr[i] = j;
//cout << j << '\n';
j ;
}
cout << '\n';
for (int i = 0; i < size; i ) {
cout << *(ptr i) << endl;
//cout << i << '\n';
}
free(ptr);
return 0;
}
I have tried dereferencing the pointer and making sure it isn't NULL. I have also printed out the result. The result being a pointer that counts 0-9. `
CodePudding user response:
double size
can be 10.1
, the condition i < 10.1
does not terminate the loop if i
is 10, the allocated buffer size is int(10.1)
, that is 10, ptr[10]
causes the buffer overrun.
CodePudding user response:
As an addedum to what 273K has answered, you can solve this problem by having size
as an int
variable. If we work with size as n int all the time, we don't have the possibility of being bitten by floating point issues when comparing in loop tests.
Let's floor the result of that division and cast to int
.
int main() {
const double h = 0.1;
const double tspan[2] = { 0.0, 1.0 };
const int size = static_cast<int>(std::floor(tspan[1] / h));
double *ptr = (double*)malloc(size * sizeof(double));
if (!ptr) {
cout << "Memory Allocation Failed";
exit(1);
}
double j = 0;
for (int i = 0; i < size; i ) {
ptr[i] = j;
//cout << j << '\n';
j ;
}
cout << '\n';
for (int i = 0; i < size; i ) {
cout << *(ptr i) << endl;
//cout << i << '\n';
}
free(ptr);
return 0;
}
Somewhat better, let's use new and delete instead of malloc and free.
int main() {
const double h = 0.1;
const double tspan[2] = { 0.0, 1.0 };
const int size = static_cast<int>(std::floor(tspan[1] / h));
double *ptr = new double[size];
if (!ptr) {
std::cout << "Memory Allocation Failed";
exit(1);
}
double j = 0;
for (int i = 0; i < size; i ) {
ptr[i] = j;
//std::cout << j << '\n';
j ;
}
std::cout << '\n';
for (int i = 0; i < size; i ) {
std::cout << *(ptr i) << std::endl;
//cout << i << '\n';
}
delete[] ptr;
return 0;
}
Better still, use std::vector
. We don't need to worry about managing the memory ourselves, and we can use smarter for loops that let the vector take care of bounds checking.
int main() {
const double h = 0.1;
const double tspan[2] = { 0.0, 1.0 };
const int size = static_cast<int>(std::floor(tspan[1] / h));
std::vector<double> vec(size);
double j = 0;
for (auto &x : vec) {
x = j;
//std::cout << j << '\n';
j ;
}
std::cout << '\n';
for (auto x : vec) {
std::cout << x << std::endl;
//std::cout << i << '\n';
}
return 0;
}
CodePudding user response:
round()
rounds to the nearest integer number. If anything, you should use ceil()
to round up.