I am implementing code for convolution in C++ (I know it exists already but I'm just doing it for practice since I'm a beginner), and while I can get the correct output, there are certain methods I'm trying that are giving unexpected output depending on how I access the values of the convolution that I store in an array and I'm not sure why.
The function code that works, whether I access the values by array indexing or with pointer incrementing, is:
void conv(int M, int* h, int L, int* x, int* y) {
int n, m = 0;
for (n = 0; n < L + M - 1; n++) {
for (m = std::max(0, n - L + 1); m <= std::min(n, M - 1); m++) {
*(y+n) += *(h + m) * *(x + n - m);
};
std::cout << "using array index: " << std::endl;
std::cout << "n = " << n << " " << "y = " << y[n] << " " << std::endl;
std::cout << std::endl;
std::cout << "using pointer: " << std::endl;
std::cout << "n = " << n << " " << "y = " << *(y+n) << " " << std::endl;
std::cout << std::endl;
//y++;
}
}
However, if I make slight changes to this (numbered below):
void conv(int M, int* h, int L, int* x, int* y) {
int n, m = 0;
for (n = 0; n < L + M - 1; n++) {
for (m = std::max(0, n - L + 1); m <= std::min(n, M - 1); m++) {
*y += *(h + m) * *(x + n - m); //[1]
};
std::cout << "using array index: " << std::endl;
std::cout << "n = " << n << " " << "y = " << y[n] << " " << std::endl;
std::cout << std::endl;
std::cout << "using pointer: " << std::endl;
std::cout << "n = " << n << " " << "y = " << *y << " " << std::endl; //[2]
std::cout << std::endl;
y++; //[3]
}
}
In this case, only accessing the values via pointer provides the correct output, while accessing it via array indexing provides random garbage.
My test code is:
int main()
{
const int M = 5; const int L = 6;
int y[M + L - 1] = {};
int x[L] = { 1, -2, 5, 3, 8, -4 };
int h[M] = { 1,2,3,4,5 };
int* yPtr = y; int* hPtr = h; int* xPtr = x;
conv(M, hPtr, L, xPtr, yPtr);
std::cout << "value after leaving conv" << std::endl;
for (int i = 0; i < M+L-1; i++) {
std::cout << "i = " << i << " " << "y = " << y[i] << std::endl;
}
}
which always provides the correct output even when accessing the array elements in the for loop of the conv provides the incorrect output.
For reference, the correct output is y = {1, 0, 4, 11, 26, 31, 53, 35, 24, -20}.
What am I doing wrong in the second example of conv to be getting the wrong values when using array indexing?
In the second version of the code, you are incrementing y as you go through the loop, so y[n] in the second version is equivalent to y[2*n] in the first. Once n reaches half the size of the array, y[n] is past the end of the array, thus garbage. *y is equivalent to y[0].
Your example is sufficiently weird to be a little difficult to read, but from your second version, this is fishy:
std::cout << "n = " << n << " " << "y = " << y[n] << " " << std::endl;
You're incrementing y as you go, so y[n] is going to go to weird places fast.
I saved Y as int * yOrig = y; and then used that, and I think I'm getting the output you expect, but I'm not sure.
Related
For example I have a function :void sort3 (int& a, int& b, int& c) and I wanted to put the variables in order and only swap if one variable is greater than the other.
for example
int v = 3, w = 4, x = 1;`
sort3(v, w, x)
I would want v to now equal 1, w to equal 3, and x to now equal 4. Essentially swapping the value if one variable would be greater than the other. Can someone show me how to do this without using the swap() function as I need this to work with C++ 98.. main function would look something like this:
int main()
{
int u = 2, v = 3, w = 4, x = 1;
cout << "before: u->" << u << ", v->" << v << endl;
sort2(u, v); // u and v are unchanged
cout << "after: u->" << u << ", v->" << v << endl;
cout << "\nbefore: w->" << w << ", x->" << x << endl;
sort2(w, x); // w now has 1, x has 4
cout << "after: w->" << w << ", x->" << x << endl;
return 0;
}
Only read to add a temp, when you need change value,
/*if a > b*/
int temp = a;
a = b;
b = a;
I am working on a c++ problem where I need to convert a vector pair of type struct to an array. My code is as follows:
struct YObject
{
YObject(unsigned int val1,
float val2,
float val3)
: m_V1(val1)
, m_V2(val2)
, m_V3(val3)
{}
unsigned int m_V1;
float m_V2;
float m_V3;
};
int result(float *output)
{
int output_size = 3*3;
std::vector<YObject> vect;
// using emplace() to insert pair in-place
vect.emplace_back(32, 24.5, 56.3);
vect.emplace_back(45, 30.3, 67.8);
vect.emplace_back(99, 78.6, 59.3);
float out[3];
for (int i=0; i<vect.size(); i++)
{
out[0]=vect[i].m_V1;
out[1]=vect[i].m_V2;
out[2]=vect[i].m_V3;
for (int n=0; n<3; n++)
{
output[n] = out[n];
//cout << output[n] << endl;
}
}
return 0;
}
int final(float *outr)
{
result(outr);
return 0;
}
int main()
{
int size = 3*3;
float arr[size];
final(arr);
cout << "arr[0]: " << arr[0] << " arr[1]: " << arr[1] << " arr[2]: " << arr[2] << " arr[3]: " << arr[3] << " arr[4]: " << arr[4] << " arr[5]: " << arr[5] << " arr[6]: " << arr[6] << " arr[7]: " << arr[7] << " arr[8]: " << arr[8];
return 0;
}
I want that the output array passed in result function to return the full vector which is formed after three emplace_back statements.
i.e. the cout statement in main function should print:
arr[0]: 32 arr[1]: 24.5 arr[2]: 56.3 arr[3]: 45 arr[4]: 30.3 arr[5]: 67.8 arr[6]: 99 arr[7]: 78.6 arr[8]: 59.3
but right now its printing:
arr[0]: 99 arr[1]: 78.6 arr[2]: 59.3arr[3]: 0 arr[4]: -1.94201e+27 arr[5]: 4.59121e-41 arr[6]: -9.96761e+17 arr[7]: -5.79801e+60 arr[8]: 1.98345e-22
If you lightly clean up your code and use std::vector there's really not much that can go wrong and it works as you expect:
#include <vector>
#include <iostream>
struct YObject
{
YObject(const unsigned int val1, const float val2, const float val3)
: m_V1(val1)
, m_V2(val2)
, m_V3(val3)
{}
unsigned int m_V1;
float m_V2;
float m_V3;
};
std::vector<float> result(const std::vector<YObject>& input)
{
std::vector<float> output;
// Easily iterate over each "input" given using for
for (auto& vect : input) {
output.push_back(vect.m_V1);
output.push_back(vect.m_V2);
output.push_back(vect.m_V3);
}
return output;
}
int main()
{
std::vector<YObject> vect;
// Define example inputs here, not deep inside a function
vect.emplace_back(32, 24.5, 56.3);
vect.emplace_back(45, 30.3, 67.8);
vect.emplace_back(99, 78.6, 59.3);
auto arr = result(vect);
std::cout << "arr[0]: " << arr[0] << " arr[1]: " << arr[1] << " arr[2]: " << arr[2] << " arr[3]: " << arr[3] << " arr[4]: " << arr[4] << " arr[5]: " << arr[5] << " arr[6]: " << arr[6] << " arr[7]: " << arr[7] << " arr[8]: " << arr[8] << std::endl;
return 0;
}
In your code you referenced arr[9] which doesn't exist in a length 9 array, the indexes are only 0 .. 8.
Try and write functions that take inputs and return useful outputs. Having a useless int return value instead of returning a new vector is one such case. Also get into the habit of declaring your arguments as const and references for non-trivial types to avoid inadvertent copies or mutations.
So I've made a basic polynomial class in C++ which stores the coefficients of these polynomials dynamically on the heap. I'm currently in the process of overloading operators so that I can add/subtract polynomials together in order to simplify them etc.
However I'm getting unexpected results when I try to overload the * operator. It looks like instead of returning the value of an index in the array it is returning the position of the array.
This is my *operator method in my .cpp file:
Polynomial Polynomial::operator*(Polynomial p) {
int maxDegree = (degree)+(p.degree - 1);
int *intArray3 = new int[maxDegree];
int i, j;
for (int i = 0; i < degree; i++) {
for (int j = 0; j < p.degree; j++) {
cout << getCoef(i) << " * " << p.getCoef(j) << " = " << getCoef(i)*p.getCoef(j) << endl;
intArray3[j] += (getCoef(i))*(p.getCoef(j));
cout << " intArray3[" << j << "] contains : " << intArray3[j] << endl;
}
}
return Polynomial(maxDegree, intArray3);}
The lines:
cout << getCoef(i) << " * " << p.getCoef(j) << " = " << getCoef(i)*p.getCoef(j) << endl;
and
cout << " intArray3[" << j << "] contains : " << intArray3[j] << endl;
return
10 * 1 = 10
intArray3[0] contains : -842150441
in my console. I'm assuming that the problem lies with my use of pointers somewhere but I can't for the life of me think why. I implemented this overload in a similar way to my + and - overloads and they work fine. Any assistance would be greatly appreciated. Cheers.
I was trying this problem and I am not concerned with the logic or algorithm of this program right now. My concern is I am getting the segmentation fault. For that I tried using gdb which showed me a "malloc : memory corruption". This problem has been haunting me as many times I use new operator and get segmentation fault. I am not able to figure out why?. But tracing output on a test case made me think something is wrong with the while loop. Please help me to correct my mistake.
Here is my code link, I was struggling to properly insert code on stackoverflow so used ideone. It also has the test case for which It gives segmentation fault.
I am getting following error message.
* Error in `./mergeoverlapping': malloc(): memory corruption: 0x0000000000a8e130 *
Aborted
(program exited with code: 134)
Press return to continue
#include <bits/stdc++.h>
using namespace std;
// debug statement
#define TRACE
#ifdef TRACE
#define trace1(x) cerr << #x << ": " << x << endl;
#define trace2(x, y) \
cerr << #x << ": " << x << " | " << #y << ": " << y << endl;
#define trace3(x, y, z) \
cerr << #x << ": " << x << " | " << #y << ": " << y << " | " << #z << ": " \
<< z << endl;
#define trace4(a, b, c, d) \
cerr << #a << ": " << a << " | " << #b << ": " << b << " | " << #c << ": " \
<< c << " | " << #d << ": " << d << endl;
#define trace5(a, b, c, d, e) \
cerr << #a << ": " << a << " | " << #b << ": " << b << " | " << #c << ": " \
<< c << " | " << #d << ": " << d << " | " << #e << ": " << e << endl;
#define trace6(a, b, c, d, e, f) \
cerr << #a << ": " << a << " | " << #b << ": " << b << " | " << #c << ": " \
<< c << " | " << #d << ": " << d << " | " << #e << ": " << e << " | " \
<< #f << ": " << f << endl;
#else
#define trace1(x)
#define trace2(x, y)
#define trace3(x, y, z)
#define trace4(a, b, c, d)
#define trace5(a, b, c, d, e)
#define trace6(a, b, c, d, e, f)
#endif
// Structure of Interval defined by nterviewbit
struct Interval {
int start;
int end;
Interval() : start(0), end(0) {}
Interval(int s, int e) : start(s), end(e) {}
};
// operator just in case I needed sorting
bool compare(Interval a, Interval b) {
if (a.start < b.start)
return true;
if (a.end < b.end)
return true;
return false;
}
// swap function to check if start is greater than end , if so then swap them
void swapp(Interval *t) {
if (t->start > t->end) {
int p = t->end;
t->end = t->start;
t->start = p;
}
}
class Solution {
public:
vector<Interval> merge(vector<Interval> &A) {
vector<Interval> ans;
sort(A.begin(), A.end(), compare);
for (int i = 0; i < (int)A.size(); i++) {
trace2(A[i].start, A[i].end);
swapp(&A[i]);
trace2(A[i].start, A[i].end);
}
int j = 0;
int sz = A.size();
while (j < sz) {
while (j + 1 < sz and
max(A[j].start, A[j + 1].start) <= min(A[j].end, A[j + 1].end)) {
Interval *x = new Interval(min(A[j].start, A[j + 1].start),
max(A[j].end, A[j + 1].end));
trace2(x->start, x->end);
trace2(A[j].start, A[j].end);
A[j] = *x;
trace2(A[j].start, A[j].end);
trace2(A[j + 1].start, A[j + 1].end);
A[j + 1] = *x;
trace2(A[j + 1].start, A[j + 1].end);
j++;
delete x;
}
ans.push_back(A[j]);
j++;
}
// for(int i=0;i<ans.size();i++){
// printf("i %d [%d %d]",i,ans[i].start,ans[i].end);
// cout<<endl;
// }
return ans;
}
};
// BEGIN CUT HERE
int main() {
Solution *obj = new Solution();
// x denotes the number of intervals
int x;
cin >> x;
vector<Interval> v;
// an interval input consist of 2 integers start and end marked by a and b
// respectively
for (int i = 0; i < x; i++) {
int a, b;
cin >> a >> b;
Interval *interval = new Interval(a, b);
trace2(interval->start, interval->end);
v.push_back(*interval);
delete interval;
}
vector<Interval> ans = obj->merge(v);
for (int i = 0; i < (int)ans.size(); i++) {
printf("i %d [%d %d]", i, ans[i].start, ans[i].end);
cout << endl;
}
}
A comparator for std::sort must define a strict weak ordering (explained e.g. here).
Your comparator doesn't. Try to compare two intervals (2,3) and (1,4), then the same intervals in the reverse order.
Thus the behaviour is undefined and your sort function may crash, or worse, corrupt the memory arena and cause a crash later.
Changing the comparator to e.g.
return a.start < b.start || a.start == b.start && a.end < b.end
should fix this crash.
I have been searching on Google an in this forum for a while, but I could not find any answer or tip for my problem. Tutorials couldn't help me either...
I want to redistribute some points, stored in a vector p_org. (x-value is stored as double).
Therefore I have the function distribute, which is defined in maths.h
distribute_tanh(&p_org_temp,&p_new_temp,iz,spacing[0],spacing[1],l_rot[(kk+1)*iz-2],status);
The function distribute_tanh does look like this:
inline void distribute_tanh (std::vector<double> *p_org, std::vector<double> *p_new, const int n_points, double spacing_begin, double spacing_end, const double total_length, double status){
//if status == 0: FLAP, if status == 1: SLAT
std::cout << "spacing_begin: " << spacing_begin << " spacing_end: " << spacing_end << std::endl;
double s_begin = spacing_begin / total_length;
double s_end = spacing_end / total_length;
double A = sqrt(s_end/s_begin);
double B = 1 / (sqrt(s_end*s_begin)*n_points);
std::cout << "A: " << A << " B: " << B << std::endl;
std::vector<double> u (n_points);
std::vector<double> sn (n_points);
double dx;
double dy;
std::cout << "Control at the beginning: p_org: " << (p_org) << " p_new: " << (p_new) << " n_points: " << n_points << " s_begin: " << s_begin << " s_end: " << s_end << " total_length: " << total_length << std::endl;
//problem no. 1
for (int i=0;i<n_points;i++){
if (B > 1.001) {
if (B < 2.7829681) {
double Bq=B-1;
dy=sqrt(6*Bq)*(1-0.15*Bq+0.057321429*pow(Bq,2)-0.024907295*pow(Bq,3)+0.0077424461*pow(Bq,4)-0.0010794123*pow(Bq,5));
} else if (B > 2.7829681) {
double Bv=log(B);
double Bw=1/B-0.028527431;
dy=Bv+(1+1/Bv)*log(2*Bv)-0.02041793+0.24902722*Bw+1.9496443*pow(Bw,2)-2.6294547*pow(Bw,3)+8.56795911*pow(Bw,4);
}
u[i]=0.5+(tanh(dy*(i*(1.0/n_points)-0.5))/(2*tanh(dy/2)));
}
else if (B < 0.999) {
if (B < 0.26938972) {
dx=M_PI*(1-B+pow(B,2)-(1+(pow(M_PI,2))/6)*pow(B,3)+6.794732*pow(B,4)-13.205501*pow(B,5)+11.726095*pow(B,6));
} else if (B > 0.26938972) {
double Bq=1-B;
dx=sqrt(6*Bq)*(1+0.15*Bq+0.057321429*pow(Bq,2)+0.048774238*pow(Bq,3)-0.053337753*pow(Bq,4)+0.075845134*pow(Bq,5));
}
u[i]=0.5+(tan(dx*(i*(1.0/n_points)-0.5))/(2*tan(dx/2)));
}
else {
u[i]=i*(1.0/n_points)*(1+2*(B-1)*(i*(1.0/n_points)-0.5)*(1-i*(1.0/n_points)));
}
sn[i]=u[i]/(A+(1.0-A)*u[i]);
std::cout << "sn(i): " << sn[i] << std::endl;
std::cout << "p_org[n_points]: " << &p_org[n_points-1] << std::endl;
if(status==0){
//p_new[i]=p_org[0]+(total_length*sn[i]);
std::cout << "FLAP maths.h" << std::endl;
}
//Here is the problem no. 2
else if(status==1){
//p_new[i]=p_org[0]-(total_length*sn[i]);
std::cout << "SLAT maths.h" << std::endl;
}
//std::cout << "p_new in math: " << p_new << std::endl;
}
}
My problem is, that I am unable to access the value of p_org or p_new. At the beginning I would like to give out the value of p_org and p_new. If I try it with a *, the compiler is complaining: error: no operator "<<" matches these operands
operand types are: std::basic_ostream> << std::vector>
std::cout << "Control at the beginning: p_org: " << (*p_org) << " p_new: " << (*p_new) << " n_points: " << n_points << " s_begin: " << s_begin << " s_end: " << s_end << " total_length: " << total_length << std::endl;
If I leave the * off, I get the addresses of p_org and p_new.
At the end of the code I would like to write the new value to p_new. If I use * to access the value, the compiler is complaining, if I leave it off, its complaining too with the following message:
error: no operator "-" matches these operands
operand types are: std::vector<double, std::allocator<double>> - double
p_new[i]=p_org[0]-(total_length*sn[i]);
^
I tried to understand both problems, but until now I had no success.
Thanks for your advice.
Your issue with the compiler error can be cut down to a very simple program.
#include <vector>
void foo(std::vector<int>* pV)
{
pV[0] = 10; // error.
}
int main()
{
std::vector<int> v(10);
foo(&v);
}
The issue is that operator[] as done above works for objects and references, not pointers. Since pv is a pointer, you must dereference it first to obtain the object, and then apply [] to the dereferenced pointer.
void foo(std::vector<int>* pV)
{
(*pV)[0] = 10; // No error
}
The other form of calling operator[] can be also used, but is a bit more verbose:
void foo(std::vector<int>* pV)
{
pv->operator[](0) = 10; // No error
}
However, to alleviate having to do this, pass the vector by reference. Then the "normal" way of using operator[] can be used.
#include <vector>
void foo(std::vector<int>& pV)
{
pV[0] = 10; // No error.
}
int main()
{
std::vector<int> v(10);
foo(v);
}