Why am I getting warning 'C6386' Buffer overrun while writing to 'ptr'? - c++

`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. `

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.

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;
}

round() rounds to the nearest integer number. If anything, you should use ceil() to round up.

Related

binary search not returning the index

this is my c++ program for binary search and for some reason it is not returning the index of the element that I searched
#include <iostream>
//using namespace std;
struct array {
int A[10];
int size;
int length;
};
void displayArray(struct array arr) {
std::cout << "the elements are :-" << std:: endl << '\t';
for (int i = 0; i < arr.length; i++) {
std::cout << arr.A[i] << ',';
}
std::cout << std::endl;
}
int binarySearch(struct array arr, int element) {
int l, h;
l = 0;
h = arr.length;
for (int i = 0; l <= h; i++) {
int mid = (l + h) / 2;
if (arr.A[mid] == element)
return mid;
else if (arr.A[mid] < element)
h = mid -1;
else
l = mid+1;
std::cout << mid << std::endl;
}
return -1;
}
int main()
{
struct array arr = {{1,2,3,4,5,6,7}, 10, 7};
int* p;
displayArray(arr);
std::cout << binarySearch(arr, 6) << std::endl;
}
I tried everything and still, it is not working for some reason
am I missing something here?
change position of l, h. you need to growth mid value if you find bigger value, the other way around, too.
#include <iostream>
using namespace std;
struct array1 {
int A[10];
int size;
int length;
};
void displayArray(struct array1 arr) {
std::cout << "the elements are :-" << std::endl << '\t';
for (int i = 0; i < arr.length; i++) {
std::cout << arr.A[i] << ',';
}
std::cout << std::endl;
}
void binarySearch(struct array1 arr, int element) {
int l, h;
l = 0;
h = arr.length;
int mid = arr.length / 2;
if (arr.A[mid] == element)
cout << "i am on index number=" << mid;
else if ( element< arr.A[mid])
for (int i = 0; 1; i++)
{
if (arr.A[i] == element)
{
cout << "i am on index number=" << i;
break;
}
}
else
for (int i = mid; 1; i++)
{
if (arr.A[i] == element)
{
cout << "i am on index number=" << i;
break;
}
}
}
int main()
{
struct array1 arr = { {1,2,3,4,5,6,7}, 10, 7 };
displayArray(arr);
binarySearch(arr, 6);
return 0;

Reliable comparison of double

I have an admittedly very basic problem: I need to compare two numbers of type double for >=. For some reason, however, my code evaluates to true for values I know to be less than the threshold.
EDIT: My code (the error occurs in the countTrig() method of the Antenna class):
#define k 0.0000000000000000000000138064852 // Boltzmann's constant
class Antenna{
vector<vector<double> > output;
int channels, smplrate, smpldur, samples, timethld;
double resistance, temp, bandwidth, lnanoise, lnagain, RMS;
public:
Antenna(
const int _channels, const int _smplrate, const int _smpldur,
const double _resistance, const double _temp, const double _bandwidth,
const double _lnanoise, const double _lnagain
){
channels = _channels; smplrate = _smplrate; smpldur = _smpldur;
resistance = _resistance; temp = _temp; bandwidth = _bandwidth;
lnanoise = _lnanoise; lnagain = _lnagain;
RMS = 2 * sqrt(4 * k * resistance * temp * bandwidth);
RMS *= lnagain * pow(10,(lnanoise/10));
samples = smplrate/smpldur;
timethld = 508; //= (1/smplrate) * 0.127;
}
void genThrml(int units);
void plotTrig(int timethld, double voltsthld);
void plotThrml();
int countTrig(double snrthld, int iter);
};
double fabs(double val){ if(val < 0){ val *= -1; } return val; }
void Antenna::genThrml(int units){
output.resize(samples, vector<double>(channels));
samples *= units;
gRandom->SetSeed(time(NULL));
for(int i = 0; i < samples; ++i){
for(int j = 0; j < channels; ++j){
output[i][j] = gRandom->Gaus(0,RMS);
}
}
}
void Antenna::plotThrml(){
//Filler
}
int Antenna::countTrig(double snrthld, int iter){
int count = 0;
int high = iter + timethld;
int low = iter - timethld;
if(low < 0){ low = 0; }
if(high > samples){ high = samples; }
for(int i = low; i < high; ++i){
for(int j = 0; j < channels; ++j){
if(output[i][j] >= snrthld) count++; std::cout << output[i][j] << " " << snrthld << "\n";
}
}
if(iter >= 3) return 1;
else return 0;
}
void Antenna::plotTrig(int timethld, double voltsthld){
double snrthld = voltsthld / RMS;
for(int i = 0; i < samples; ++i){
for(int j = 0; j < channels; ++j){
countTrig(snrthld, i);
}
}
}
int main(){
Antenna test(20,4000,1,50,290,500000000,1.5,60);
test.genThrml(1);
test.plotTrig(400,0.0005);
return 0;
}
With a threshold of 0.147417, I get output like this:
0.0014238
-0.00187276
I believe I understand the problem (unless there's some obvious mistake I've made and not caught), and I understand the reasoning behind floating point errors, precision, etc. I don't, however, know, what the best practice is here. What is a good solution? How can I reliably compare values of type double? This will be used in an application where it is very important that values be precise and comparisons be reliable.
EDIT: A smaller example:
int countTrig(double snrthld, int iter, vector<vector<double> > output, int timethld){
int count = 0;
int high = iter + timethld;
int low = iter - timethld;
if(low < 0){ low = 0; }
if(high > 3){ high = 3; }
for(int i = low; i < high; ++i){
for(int j = 0; j < 3; ++j){
if(fabs(output[i][j]) >= snrthld) count++; std::cout << output[i][j] << " " << snrthld << "\n";
}
}
if(iter >= 3) return 1;
else return 0;
}
void plotTrig(int timethld, double snrthld){
vector<vector<double> > output = {{0.000028382, -0.0028348329, -0.00008573829},
{0.183849939, 0.9283829020, -0.92838200021},
{-0.00292889, 0.2399229929, -0.00081009189}};
for(int i = 0; i < 3; ++i){
for(int j = 0; j < 3; ++j){
countTrig(snrthld, i, output, timethld);
}
}
}
int main(){
plotTrig(1,0.1);
return 0;
}
You have a typo.
if(output[i][j] >= snrthld) count++; std::cout << output[i][j] << " " << snrthld << "\n";
this line means
if(output[i][j] >= snrthld)
count++;
std::cout << output[i][j] << " " << snrthld << "\n";
aka
if(output[i][j] >= snrthld)
{
count++;
}
std::cout << output[i][j] << " " << snrthld << "\n";
and you want:
if(output[i][j] >= snrthld)
{
count++;
std::cout << output[i][j] << " " << snrthld << "\n";
}

vector is out of range,but why?

It says my vector is out of range for ArrayD. But I do not understand why. Everything else works. Is says that the vector is out of range after double deez. Therefore, it will not ascend fully.
using namespace std;
void hello();
void Infile();
double x, y, z;
double P, B;
int E = 0;
double V[16];
double C[16];
double D[16];
int m, n;
int main()
{
Infile();
return 0;
}
void Infile()
{
ifstream fileA("P_matrix.txt");
ifstream fileB("b_matrix.txt");
ifstream fileC("d_matrix.txt");
vector<double>ArrayP;
vector<double>ArrayB;
vector<double>ArrayD;
cout << "P Matrix Values \n";
while (fileA.good())
{
fileA >> P;
ArrayP.push_back(P);
}
for (int i = 0; i<ArrayP.size(); i++)
{
cout << ArrayP[i] << ",";
}
system("pause");
cout << "B Matrix Values \n";
while (fileB.good())
{
fileB >> B;
ArrayB.push_back(B);
}
for (int j = 0; j < 16; j++)
{
cout << ArrayB[j] << ",";
}
system("pause");
while (fileC.good())
{
fileC >> D;
ArrayD.push_back(D);
}
for (int k = 0; k <16; k++)
{
cout << ArrayD[k] << ",";
}
system("pause");
for (int m = 0; m < 16; m++)
{
V[m] = ArrayP[m] * ArrayB[m];
cout << V[m] << ",";
}
system("pause");
for (int n = 0; n < 16; n++)
{
C[n] = V[n] * ArrayD[n];
cout << C[n] << ",";
}
//outfile.close();
system("pause");
double deez;
for (int d = 0; d < 16; d++) //acscending
{
for (int q = 0; q < 16; q++)
{
if (ArrayD[q] < ArrayD[q - 1])
{
deez = ArrayD[q];
ArrayD[q] = ArrayD[q - 1];
ArrayD[q - 1] = deez;
}
}
}
for (int q = 0; q < 16; q++)
cout << C[q] << ",";
system("pause");
double nutz;
for (int d = 0; d < 16; d++) //descending
{
for (int q = 0; q < 16; q++)
{
if (V[q] < V[q + 1])
{
nutz = V[q];
V[q] = V[q + 1];
V[q + 1] = nutz;
}
}
}
for (int q = 0; q < 16; q++)
cout << V[q] << ",";
system("pause");
return;
}
Here, q starts at zero, so you are attempting to access index [-1].
ArrayD[q - 1]
When iterating over ArrayP, you correctly do:
for (int i = 0; i<ArrayP.size(); i++)
However for ArrayB and ArrayC, you seem to assume there are only ever 16 elements in those arrays (are you sure?). I can't see any evidence that the arrays are restricted to always having 16 elements in code, so that could also be the issue.
Later still, you then seem to assume all of those arrays have 16 elements?
for (int m = 0; m < 16; m++)
{
V[m] = ArrayP[m] * ArrayB[m];
cout << V[m] << ",";
}
Those are the obvious places that could cause an out of range error.

How to implement insertion sort algorithm in C++ with arrays and pointers?

I am trying to learn C++, arrays and pointers. I decided to implement the insertion sort algorithm. So, here is my code and my wrong output. What should I do to correct it? Can you please tell me what is my mistake and what should I avoid if it is a common error?
My code:
// InsertionSort.cpp
#include "stdafx.h"
#include <iostream>
int DeclareAnInteger();
int* DeclareAndShowTheArray(int n);
int* InsertionSort(int *A, int n);
int main()
{
int n = DeclareAnInteger();
int *A;
A = DeclareAndShowTheArray(n);
int *B;
B = InsertionSort(A, n);
system("PAUSE");
return 0;
}
int DeclareAnInteger()
{
int n;
std::cout << "Please enter a positive integer n: ";
std::cin >> n;
return n;
}
int* DeclareAndShowTheArray(int n)
{
int *A;
A = (int *)alloca(sizeof(int) * n);
for (int i = 0; i < n; i++)
{
std::cout << "Please enter the value of A[" << i + 1 << "]: ";
std::cin >> A[i];
}
std::cout << "The unsorted array is: ";
for (int i = 0; i < n; i++)
{
std::cout << A[i];
std::cout << "\t";
}
std::cout << "\n";
return A;
}
int* InsertionSort(int *A, int n)
{
int k;
//int *A = new int[n];
for (k = 1; k < n; k++)
{
int key = A[k];
int m = k - 1;
while (m >= 0 & A[m] > key)
{
A[m + 1] = A[m];
m = m - 1;
}
A[m + 1] = key;
}
std::cout << "The sorted array is: ";
for (int i = 0; i < n; i++)
{
std::cout << A[i];
std::cout << "\t";
}
std::cout << "\n" << std::endl;
return A;
}
My output:
This here is a big problem:
A = (int *)alloca(sizeof(int) * n);
The alloca function allocates on the stack, and it will be lost when the function returns which gives you a stray pointer and undefined behavior when you dereference this pointer.
If you're programming C++ then use new, if you program C then use malloc.

New set of values for testcases using srand() in c++

I am trying to create some test cases for my 'minimum dot product' problem. I want 10 test cases , each generating different set of values for both vector a and b.
The Problem is that even after using srand( time( NULL ) ) though a new input is generated every time I compile and run the code but that same input is used for all the 10 test cases.
#include <algorithm>
#include <iostream>
#include <vector>
#include <cstdlib>
#include <ctime>
using std::vector;
void sort_asc(vector<int> &manav, int sizes)
{
int temp = 0;
for (int i = 0; i<sizes; i++)
{
for (int j = i + 1; j<sizes; j++)
{
if (manav[i] > manav[j])
{
temp = manav[i];
manav[i] = manav[j];
manav[j] = temp;
}
}
}
std::cout << "b in asc order : ";
for (int i = 0; i<sizes; i++)
{
std::cout << manav[i] << " ";
}
std::cout << std::endl;
}
void sort_desc(vector<int> &manav, int sizes)
{
int temp = 0;
for (int i = 0; i<sizes; i++)
{
for (int j = i + 1; j<sizes; j++)
{
if (manav[i] < manav[j])
{
temp = manav[i];
manav[i] = manav[j];
manav[j] = temp;
}
}
}
std::cout << "a in desc : ";
for (int i = 0; i<sizes; i++)
{
std::cout << manav[i] << " ";
}
std::cout << std::endl;
}
long long min_dot_product(vector<int> a, vector<int> b, int sizes) {
long long result = 0;
sort_desc(a, sizes);
sort_asc(b, sizes);
for (size_t i = 0; i < sizes; i++) {
result += a[i] * b[i];
}
return result;
}
int main() {
srand(time(NULL));
/*
std::cin >> n;
vector<int> a(n), b(n);
for (size_t i = 0; i < n; i++) {
std::cin >> a[i];
}
for (size_t i = 0; i < n; i++) {
std::cin >> b[i];
}
*/
//================================================================ TESTING =========================================================================
int z = 0;
int n = (rand() % 10) + 1; // generating the size of the vectors [1-10]
std::cout << "n = " << n << "\n";
vector<int> a;
vector<int> b;
while (z != 10) {
for (int i = 0; i < n; ++i)
{
int p = (rand() % 10) - 5;
a.push_back(p); // input values [-5,4] in 'a'
}
std::cout << "Unsorted Vector a = ";
for (int i = 0; i<n; i++)
{
std::cout << a[i] << " ";
}
std::cout << std::endl;
for (int i = 0; i < n; ++i)
{
int q = (rand() % 10) - 5;
b.push_back(q); // inputing values [-5,4] in 'b'
}
std::cout << "Unsorted Vector b = ";
for (int i = 0; i<n; i++)
{
std::cout << b[i] << " ";
}
std::cout << std::endl;
std::cout << "min_dot_product = " << min_dot_product(a, b, n) << std::endl;
z++;
}
return 0;
}
I somehow want to generate a different set of values for vector a and b for all of the 10 test cases every time I run the code.
I have tried srand(i) within the respective for loops before pushing the value in vectors but its not working for me, also reusing srand( time( NULL ) ) within the for loops is not gonna help either. Is there some other simple way I can achieve this?
The problem is you never clear out the vector on each iteration. Since you don't all of the new random numbers you generate are being added to the end of the vector and you ignore them since n never changes.
What you need to do is add
a.clear();
b.clear();
to the end of the while loop. This will clear out the vectors and then when you start the next iteration the new random numbers will get added into the part of the vector you use in your functions.
You could also set the vector the proper size and then use [] to access the elements. This way you would just overwrite the previous values and you would not have to call clear()
vector<int> a(n);
vector<int> b(n);
//...
for (int i = 0; i < n; ++i)
{
a[i] = (rand() % 10) - 5;
b[i] = (rand() % 10) - 5;
}
I put both assignments in the same for loop to save space. You can do this in two separate loops but it is not needed.