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.
Related
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.
I am doing a program to test swapping couple of things by reference.
I managed to get the first two functions in my code to work but can't get to change the char * in the third function.
I think the problem is that it's a constant and only valid to read-only
that's what the error is telling me but How to be able to work with it in this way?
Here is the code:
#include <iostream>
using namespace std;
void swapping(int &x, int &y)
{
int temp =x;
x=y;
y=temp;
}
void swapping(float &x, float &y)
{
float temp=x;
x=y;
y=temp;
}
void swapping(const char *&x,const char *&y)
{
int help = *x;
(*x)=(*y);
(*y)=help;
} // swap char pointers
int main(void) {
int a = 7, b = 15;
float x = 3.5, y = 9.2;
const char *str1 = "One";
const char *str2 = "Two";
cout << "a=" << a << ", b=" << b << endl;
cout << "x=" << x << ", y=" << y << endl;
cout << "str1=" << str1 << ", str2=" << str2 << endl;
swapping(a, b);
swapping(x, y);
swapping(str1, str2);
cout << "\n";
cout << "a=" << a << ", b=" << b << endl;
cout << "x=" << x << ", y=" << y << endl;
cout << "str1=" << str1 << ", str2=" << str2 << endl;
return 0;
}
As suggested in the comments:
void swapping(const char*& x, const char*& y)
{
auto t = x;
x = y;
y = t;
}
Now you should consider to use a template:
template<typename Type>
void swapping(Type& a, Type& b)
{
auto t = a;
a = b;
b = t;
}
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);
}
This test example I've made works as expected:
FLAC__int32 array[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
FLAC__int32 const *const handle(array);
FLAC__int32 temp[10];
std::vector<FLAC__int32> base;
base.resize(10);
memcpy(&base[0], handle, 10 * sizeof(FLAC__int32));
for (size_t i(0); i < 10; i++)
cout << endl << "[ " << i << " ] " << base[i];
However, with the code below, I can't get the memcpy to work correctly. How do I correct this so that memcpy makes correct copies of the buffer?
Note: _buffer contains binary data which was decoder by libFLAC.
FLAC__StreamDecoderWriteStatus
Source::write_callback
(FLAC__Frame const* _frame, FLAC__int32 const *const _buffer[])
{
cout << endl << "Head index [ " << index_ << " ].";
memcpy(&data_[index_], &_buffer[0], _frame->header.blocksize *
sizeof(FLAC__int32));
index_ += _frame->header.blocksize;
cout << endl << "Tail index [ " << index_ << " ].";
for(size_t i(0); i < 400; i++) {
cout << endl << "Buff [ " << i << " ] " << _buffer[i];
cout << endl << "Data [ " << i << " ] " << data_[i];
} // jump
return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
} // main
And below is how I resize the vector and reset the index:
void
Source::metadata_callback (const ::FLAC__StreamMetadata *metadata)
{
...
total_samples_ = metadata->data.stream_info.total_samples;
...
data_.resize(total_samples_); index_ = 0;
} // main
You want a deep copy (that is, you want to copy the FLAC__int32 values, not the pointers to them), and you don't seem to care whether you construct a container of those values or of pointers to those values. So memcpy is the wrong tool. Let's start with a very simple case:
void foo(int * buf)
{
int data = *buf;
}
Then try copying an array to a vector:
void foo(int * buf[])
{
vector<int> data(10);
for(unsigned int k=0; k<3; ++k)
data[k] = *buf[k];
}
Then the full solution:
FLAC__StreamDecoderWriteStatus Source::write_callback(FLAC__Frame const* _frame, FLAC__int32 const *const _buffer[])
{
cout << endl << "Head index [ " << index_ << " ].";
data_.resize(_frame->header.blocksize);
for(size_t k=0; k<_frame->header.blocksize; ++k)
{
data_[index_+k] = *_buffer[k];
}
index_ += _frame->header.blocksize;
cout << endl << "Tail index [ " << index_ << " ].";
for(size_t i(0); i < 400; i++)
{
cout << endl << "Buff [ " << i << " ] " << *_buffer[i];
cout << endl << "Data [ " << i << " ] " << data_[i];
}
return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
}
I need to do the following:
Assume that the C++ array
int fib[] = { 0, 1, 1, 2, 3, 5, 8, 13, 21 };
is stored on a 32-bit machine, at memory address 0xA0000000 (hexadecimal). What are the values of the following expressions?
fib
*fib
&fib[0]
&fib[6]
*(fib+7)
I tried writing this code to try and print out the desired values.
int main()
{
int i = 0;
int *p = &A0000000;
cout << "i= " << i << endl;
cout << "p= " << p << endl;
*p = 0;
cout << "i=" << i << endl;
int &r = i;
r = 0;
cout << "i= " << i << endl;
int fib[] = { 0, 1, 1, 2, 3, 5, 8, 13, 21 };
cout << "fib= " << fib << endl;
cout << "*(*fib)= " << *fib << endl;
cout << "&fib[0]= " << &fib[0] << endl;
cout << "*(fib+7)= " << *(fib+7) << endl;
cout << "&fib[6]= " << &fib[6] << endl;
system("PAUSE");
return 0;
}
I get the following error message:
c:\users\inquirer\documents\visual studio 2010\projects\fib1\fib1\fib1.cpp(7): error C2065: 'A0000000' : undeclared identifier
Thank you in advance for the help. What do I need to do to print out the correct values?
To fix the compilation error try
int* p=(int*)0xA0000000;
Whatever this should be good for ...
You cannot store something at an arbitrary virtual memory address.
*p = 0; will crash at runtime, because 0xa0000000 is probably not a valid location to write to.
Try int *p = new int and print the address you got. It will be less beautiful than 0xa0000000 but it will be sufficient to visuallise your experiment.