Integer overflow and std::stoi - c++

if x > INT_MAX or if x > INT_MIN the function will return 0... or that's what i'm trying to do :)
in my test case i pass in a value that is INT_MAX + 1... 2147483648 ... to introduce integer overflow to see how the program handles it.
i step through... my IDE debugger says that the value immediately goes to -2147483648 upon overflow and for some reason the program executes beyond both of these statements:
if (x > INT_MAX)
if (x < INT_MIN)
and keeps crashes at int revInt = std::stoi(strNum);
saying out of range
Must be something simple, but it's got me stumped. Why isn't the program returning before it ever gets to that std::stoi() given x > INT_MAX? Any help appreciated. Thanks! Full listing of function and test bed below: (sorry having trouble with the code insertion formatting..)
#include <iostream>
#include <algorithm>
#include <string> //using namespace std;
class Solution {
public: int reverse(int x)
{
// check special cases for int and set flags:
// is x > max int, need to return 0 now
if(x > INT_MAX)
return 0;
// is x < min int, need to return 0 now
if(x < INT_MIN)
return 0;
// is x < 0, need negative sign handled at end
// does x end with 0, need to not start new int with 0 if it's ploy numeric and the functions used handle that for us
// do conversion, reversal, output:
// convert int to string
std::string strNum = std::to_string(x);
// reverse string
std::reverse(strNum.begin(), strNum.end());
// convert reversed string to int
int revInt = std::stoi(strNum);
// multiply by -1 if x was negative
if (x < 0)
revInt = revInt * -1;
// output reversed integer
return revInt;
}
};
Main:
#include <iostream>
int main(int argc, const char * argv[]) {
// test cases
// instance Solution and call it's method
Solution sol;
int answer = sol.reverse(0); // 0
std::cout << "in " << 0 << ", out " << answer << "\n";
answer = sol.reverse(-1); // -1
std::cout << "in " << -1 << ", out " << answer << "\n";
answer = sol.reverse(10); // 1
std::cout << "in " << 10 << ", out " << answer << "\n";
answer = sol.reverse(12); // 21
std::cout << "in " << 12 << ", out " << answer << "\n";
answer = sol.reverse(100); // 1
std::cout << "in " << 100 << ", out " << answer << "\n";
answer = sol.reverse(123); // 321
std::cout << "in " << 123 << ", out " << answer << "\n";
answer = sol.reverse(-123); // -321
std::cout << "in " << -123 << ", out " << answer << "\n";
answer = sol.reverse(1024); // 4201
std::cout << "in " << 1024 << ", out " << answer << "\n";
answer = sol.reverse(-1024); // -4201
std::cout << "in " << -1024 << ", out " << answer << "\n";
answer = sol.reverse(2147483648); // 0
std::cout << "in " << 2147483648 << ", out " << answer << "\n";
answer = sol.reverse(-2147483648); // 0
std::cout << "in " << -2147483648 << ", out " << answer << "\n";
return 0;
}

Any test like (x > INT_MAX) with x being of type int will never evaluate to true, since the value of x cannot exceed INT_MAX.
Anyway, even if 2147483647 would be a valid range, its reverse 7463847412 is not.
So I think its better to let stoi "try" to convert the values and "catch" any out_of_range-exception`. The following code illustrates this approach:
int convert() {
const char* num = "12345678890123424542";
try {
int x = std::stoi(num);
return x;
} catch (std::out_of_range &e) {
cout << "invalid." << endl;
return 0;
}
}

Related

Is it possible to have memory problems that don’t crash a program?

I wrote a text cipher program. It seems to works on text strings a few characters long but does not work on a longer ones. It gets the input text by reading from a text file. On longer text strings, it still runs without crashing, but it doesn’t seem to work properly.
Below I have isolated the code that performs that text scrambling. In case it is useful, I am running this in a virtual machine running Ubuntu 19.04. When running the code, enter in auto when prompted. I removed the rest of code so it wasn't too long.
#include <iostream>
#include <string>
#include <sstream>
#include <random>
#include <cmath>
#include <cctype>
#include <chrono>
#include <fstream>
#include <new>
bool run_cypher(char (&a)[27],char (&b)[27],char (&c)[11],char (&aa)[27],char (&bb)[27],char (&cc)[11]) {
//lowercase cypher, uppercase cypher, number cypher, lowercase original sequence, uppercase original sequence, number original sequence
std::ifstream out_buffer("text.txt",std::ios::in);
std::ofstream file_buffer("text_out.txt",std::ios::out);
//out_buffer.open();
out_buffer.seekg(0,out_buffer.end);
std::cout << "size of text: " << out_buffer.tellg() << std::endl;//debug
const int size = out_buffer.tellg();
std::cout << "size: " << size << std::endl;//debug
out_buffer.seekg(0,out_buffer.beg);
char *out_array = new char[size + 1];
std::cout << "size of out array: " << sizeof(out_array) << std::endl;//debug
for (int u = 0;u <= size;u = u + 1) {
out_array[u] = 0;
}
out_buffer.read(out_array,size);
out_buffer.close();
char original[size + 1];//debug
for (int bn = 0;bn <= size;bn = bn + 1) {//debug
original[bn] = out_array[bn];//debug
}//debug
for (int y = 0;y <= size - 1;y = y + 1) {
std::cout << "- - - - - - - -" << std::endl;
std::cout << "out_array[" << y << "]: " << out_array[y] << std::endl;//debug
int match;
int case_n; //0 = lowercase, 1 = uppercase
if (isalpha(out_array[y])) {
if (islower(out_array[y])) {
//std::cout << "out_array[" << y << "]: " << out_array[y] << std::endl;//debug
//int match;
for (int ab = 0;ab <= size - 1;ab = ab + 1) {
if (out_array[y] == aa[ab]) {
match = ab;
case_n = 0;
std::cout << "matched letter: " << aa[match] << std::endl;//debug
std::cout << "letter index: " << match << std::endl;//debug
std::cout << "case_n: " << case_n << std::endl;//debug
}
}
}
if (isupper(out_array[y])) {
for (int cv = 0;cv <= size - 1;cv = cv + 1) {
if (out_array[y] == bb[cv]) {
case_n = 1;
match = cv;
std::cout << "matched letter: " << bb[match] << std::endl;//debug
std::cout << "letter index: " << match << std::endl;//debug
std::cout << "case_n: " << case_n << std::endl;//debug
}
}
}
if (case_n == 0) {
out_array[y] = a[match];
std::cout << "replacement letter: " << a[match] << " | new character: " << out_array[y] << std::endl;//debug
}
if (case_n == 1) {
std::cout << "replacement letter: " << b[match] << " | new character: " << out_array[y] << std::endl;//debug
out_array[y] = b[match];
}
}
if (isdigit(out_array[y])) {
for (int o = 0;o <= size - 1;o = o + 1) {
if (out_array[y] == cc[o]) {
match = o;
std::cout << "matched letter: " << cc[match] << std::endl;//debug
std::cout << "letter index: " << match << std::endl;//debug
}
}
out_array[y] = c[match];
std::cout << "replacement number: " << c[match] << " | new character: " << out_array[y] << std::endl;//debug
}
std::cout << "- - - - - - - -" << std::endl;
}
std::cout << "original text: " << "\n" << original << "\n" << std::endl;
std::cout << "encrypted text: " << "\n" << out_array << std::endl;
delete[] out_array;
return 0;
}
int main() {
const int alpha_size = 27;
const int num_size = 11;
char l_a_set[] = "abcdefghijklmnopqrstuvwxyz";
char cap_a_set[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
char n_a_set[] = "0123456789";
std::cout << "sizeof alpha_set: " << std::endl;//debug
char lower[alpha_size] = "mnbvcxzasdfghjklpoiuytrewq";
char upper[alpha_size] = "POIUYTREWQASDFGHJKLMNBVCXZ";
char num[num_size] = "9876543210";
int p_run; //control variable. 1 == running, 0 == not running
int b[alpha_size]; //array with values expressed as index numbers
std::string mode;
int m_set = 1;
while (m_set == 1) {
std::cout << "Enter 'auto' for automatic cypher generation." << std::endl;
std::cout << "Enter 'manual' to manually enter in a cypher. " << std::endl;
std::cin >> mode;
std::cin.ignore(1);
std::cin.clear();
if (mode == "auto") {
p_run = 2;
m_set = 0;
}
if (mode == "manual") {
p_run = 3;
m_set = 0;
}
}
if (p_run == 2) { //automatic mode
std::cout <<"lower cypher: " << lower << "\n" << "upper cypher: " << upper << "\n" << "number cypher: " << num << std::endl;//debug
run_cypher(lower,upper,num,l_a_set,cap_a_set,n_a_set);
return 0;//debug
}
while (p_run == 3) {//manual mode
return 0;//debug
}
return 0;
}
For example, using an array containing “mnbvcxzasdfghjklpoiuytrewq” as the cipher for lower case letters, I get “mnbv” if the input is “abcd”. This is correct.
If the input is “a long word”, I get “m gggz zzzv” as the output when it should be “m gkjz rkov”. Sort of correct but still wrong. If I use “this is a very very long sentence that will result in the program failing” as the input, I get "uas” as the output, which is completely wrong. The program still runs but it fails to function as intended. So as you can see, it does work, but not on any text strings that are remotely long. Is this a memory problem or did I make horrible mistake somewhere?
For your specific code, you should run it through a memory checking tool such as valgrind, or compile with an address sanitizer.
Here are some examples of memory problems that most likely won't crash your program:
Forgetting to delete a small object, which is allocated only once in the program. A memory leak can remain undetected for decades, if it does not make the program run out of memory.
Reading from allocated uninitialized memory. May still crash if the system allocates objects lazily at the first write.
Writing out of bounds slightly after an object that sits on heap, whose size is sizeof(obj) % 8 != 0. This is so, since heap allocation is usually done in multiples of 8 or 16. You can read about it at answers of this SO question.
Dereferencing a nullptr does not crash on some systems. For example AIX used to put zeros at and near address 0x0. Newer AIX might still do it.
On many systems without memory management, address zero is either a regular memory address, or a memory mapped register. This memory can be accessed without crashing.
On any system I have tried (POSIX based), it was possible to allocate valid memory at address zero through memory mapping. Doing so can even make writing through nullptr work without crashing.
This is only a partial list.
Note: these memory problems are undefined behavior. This means that even if the program does not crash in debug mode, the compiler might assume wrong things during optimization. If the compiler assumes wrong things, it might create an optimized code that crashes after optimization.
For example, most compilers will optimize this:
int a = *p; // implies that p != nullptr
if (p)
boom(p);
Into this:
int a = *p;
boom(p);
If a system allows dereferencing nullptr, then this code might crash after optimization. It will not crash due to the dereferencing, but because the optimization did something the programmer did not foresee.

What's wrong in my if statements logic?

In this little program I try to order 3 numbers in a descending order. But seems like the line in which has "// 3 2 1 - doesn't work" as a comment isn't working as expected. It seems like my logic is correct.
My input:
4,
554 and
454545
Output: (which is not what I wanted)
554, 454545 and 4
If the value hold on the integer numbThree is bigger than numbOne and if numbOne is NOT bigger than numbTwo (NOT == else) it should ouput numbThree, numbTwo and numbOne in this order, why doesn't it work?
#include <iostream>
int main() {
int numbOne = 0, numbTwo = 0, numbThree = 0;
std::cin >> numbOne >> numbTwo >> numbThree;
if (numbOne > numbTwo) {
if (numbTwo > numbThree) {
std::cout << numbOne << " " << numbTwo << " " << numbThree << std::endl; // 1 2 3
}
else {
std::cout << numbOne << " " << numbThree << " " << numbTwo<< std::endl; // 1 3 2
}
}
else if (numbTwo > numbOne) {
if (numbOne > numbThree) {
std::cout << numbTwo << " " << numbOne << " " << numbThree << std::endl; // 2 1 3 - works
}
else {
std::cout << numbTwo << " " << numbThree << " " << numbOne << std::endl; // 2 3 1
}
}
else if (numbThree > numbOne) {
if (numbOne > numbTwo) {
std::cout << numbThree << " " << numbOne << " " << numbTwo << std::endl; // 3 1 2
}
else {
std::cout << numbThree << " " << numbTwo << " " << numbOne << std::endl; // 3 2 1 - doesn't work
}
}
std::cin.get();
std::cin.ignore();
return 0;
}
Thanks in advance for helping me out.
You cannot, in general, sort 3 numbers with 2 comparisons (see YSC's comment for a hard reason in terms of information content). Already your case 1 3 2 is flawed: what if numbThree > numbOne?
In general you have to allow for up to 3 comparisons. Of course, you can simply use the sort functionality provided by the standard library (i.e. by the language). If you don't want to (for some reason), then the correct logic (for ascending order) is
if(a<b)
if (b<c) // a,b,c // 2 comparisons
else if(a<c) // a,c,b // 3 comparisons
else // c,a,b // 3 comparisons
else
if( (a<c) // b,a,c // 2 comparisons
else if(b<c) // b,c,a // 3 comparisons
else // c,b,a // 3 comparisons
Thus, in 4 out of 6 possible cases we need 3 rather than 2 comparisons.
Not intended as an answer, but as an illustration of the comment by Sam Varshavchik:
What's wrong is that the code should use a small array, and std::sort,
instead of this kind of spaghetti code.
While Sam is right about production code, as an exercise of how to implement the logic, the question is okay and there is already a solution.
#include <iostream>
#include <vector>
#include <algorithm>
int main()
{
std::vector<int> v(3);
if (! (std::cin >> v[0] >> v[1] >> v[2])) { exit(-1); }
std::sort(v.begin(), v.end(), std::greater<int>());
for (auto c: v) { std::cout << c << " "; }
std::cout << "\n";
}

Significant figures in C++

I've written a program that calculates values in a series and all of the values are particularly lengthy doubles. I want to print these values each displaying 15 significant figures. Here's some code that illustrates the issue I'm having:
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
double x = 0.12345678901234567890;
double y = 1.12345678901234567890;
cout << setprecision(15) << fixed << x << "\t" << y << "\n";
return 0;
}
With just setprecision trailing zeros are not shown so I added fixed as I have seen in other answers on this site. However, now I just seem to have 15 decimal places and for values that aren't 0.something this is not what I want. You can see this from the output of the above:
0.123456789012346 1.123456789012346
The first number has 15 sig figs but the second has 16. What can I do to resolve this?
EDIT: I have been specifically asked to use setprecision, so I am unable to try cout.precision.
You can simply use scientific (note the 14 instead of 15):
std::cout << std::scientific << std::setprecision(14) << -0.123456789012345678 << std::endl;
std::cout << std::scientific << std::setprecision(14) << -1.234567890123456789 << std::endl;
-1.23456789012346e-01
-1.23456789012346e+00
or you can use a function:
#include <iostream>
#include <vector>
#include <iomanip>
#include <string>
#include <sstream>
enum vis_opt { scientific, decimal, decimal_relaxed };
std::string figures(double x, int nfig, vis_opt vo=decimal) {
std::stringstream str;
str << std::setprecision(nfig-1) << std::scientific << x;
std::string s = str.str();
if ( vo == scientific )
return s;
else {
std::stringstream out;
std::size_t pos;
int ileft = std::stoi(s,&pos);
std::string dec = s.substr(pos + 1, nfig - 1);
int e = std::stoi(s.substr(pos + nfig + 1));
if ( e < 0 ) {
std::string zeroes(-1-e,'0');
if ( ileft < 0 )
out << "-0." << zeroes << -ileft << dec;
else
out << "0." << zeroes << ileft << dec;
} else if ( e == 0) {
out << ileft << '.' << dec;
} else if ( e < ( nfig - 1) ) {
out << ileft << dec.substr(0,e) << '.' << dec.substr(e);
} else if ( e == ( nfig - 1) ) {
out << ileft << dec;
} else {
if ( vo == decimal_relaxed) {
out << s;
} else {
out << ileft << dec << std::string(e - nfig + 1,'0');
}
}
return out.str();
}
}
int main() {
std::vector<double> test_cases = {
-123456789012345,
-12.34567890123456789,
-0.1234567890123456789,
-0.0001234,
0,
0.0001234,
0.1234567890123456789,
12.34567890123456789,
1.234567890123456789,
12345678901234,
123456789012345,
1234567890123456789.0,
};
for ( auto i : test_cases) {
std::cout << std::setw(22) << std::right << figures(i,15,scientific);
std::cout << std::setw(22) << std::right << figures(i,15) << std::endl;
}
return 0;
}
My output is:
-1.23456789012345e+14 -123456789012345
-1.23456789012346e+01 -12.3456789012346
-1.23456789012346e-01 -0.123456789012346
-1.23400000000000e-04 -0.000123400000000000
0.00000000000000e+00 0.00000000000000
1.23400000000000e-04 0.000123400000000000
1.23456789012346e-01 0.123456789012346
1.23456789012346e+01 12.3456789012346
1.23456789012346e+00 1.23456789012346
1.23456789012340e+13 12345678901234.0
1.23456789012345e+14 123456789012345
1.23456789012346e+18 1234567890123460000
I've found some success in just computing the integer significant figures, and then setting the floating significant figures to be X - <integer sig figs>:
Edit
To address Bob's comments, I'll account for more edge cases. I've refactored the code somewhat to adjust the field precision based on leading and trailing zeros. There would still be an edge case I believe for very small values (like std::numeric_limits<double>::epsilon:
int AdjustPrecision(int desiredPrecision, double _in)
{
// case of all zeros
if (_in == 0.0)
return desiredPrecision;
// handle leading zeros before decimal place
size_t truncated = static_cast<size_t>(_in);
while(truncated != 0)
{
truncated /= 10;
--desiredPrecision;
}
// handle trailing zeros after decimal place
_in *= 10;
while(static_cast<size_t>(_in) == 0)
{
_in *= 10;
++desiredPrecision;
}
return desiredPrecision;
}
With more tests:
double a = 0.000123456789012345;
double b = 123456789012345;
double x = 0.12345678901234567890;
double y = 1.12345678901234567890;
double z = 11.12345678901234567890;
std::cout.setf( std::ios::fixed, std:: ios::floatfield);
std::cout << "a: " << std::setprecision(AdjustPrecision(15, a)) << a << std::endl;
std::cout << "b: " << std::setprecision(AdjustPrecision(15, b)) << b << std::endl;
std::cout << "x " << std::setprecision(AdjustPrecision(15, x)) << x << std::endl;
std::cout << "y " << std::setprecision(AdjustPrecision(15, y)) << y << std::endl;
std::cout << "z: " << std::setprecision(AdjustPrecision(15, z)) << z << std::endl;
Output:
a: 0.000123456789012345
b: 123456789012345
x 0.123456789012346
y 1.12345678901235
z: 11.1234567890123
Live Demo
int GetIntegerSigFigs(double _in)
{
int toReturn = 0;
int truncated = static_cast<int>(_in);
while(truncated != 0)
{
truncated /= 10;
++toReturn;
}
return toReturn;
}
(I'm sure there are some edge cases I'm missing)
And then using it:
double x = 0.12345678901234567890;
double y = 1.12345678901234567890;
std::cout << td::setprecision(15-GetIntegerSigFigs(x)) << x
<< "\t" << std::setprecision(15-GetIntegerSigFigs(y)) << y << "\n";
Prints:
0.123456789012346 1.12345678901235
Live Demo

fibonacci print out issue in c++

I was trying to run the fib.exe by using this command "fib 12" so it can directly print out the result in this format:
http://pastebin.com/ytR92i8f
But with my code compiled, for instance, if I use 12 to test my program, it won' t read any number and show the result in this command "fib xx" but it will run the program and let you type the number you want in the next line and then print out the result...
I have attached the link to my main.cpp below as reference.
main.cpp : http://pastebin.com/fhUAkNQR
Because main.c can not be modify so I can only use one function to get it works.
Right now I already have the correct result.
void fibonacci(int max)
{
do
{
std::cin >> max;
}
while(max < 2 && max > 46);
std::cout << " Fibonacci Fibonacci" << std::endl;
std::cout << " N number quotient" << std::endl;
std::cout << "-------------------------------------" << std::endl;
std::cout << " 0 0 N/A" << std::endl;
std::cout << " 1 1 N/A" << std::endl;
int count = max;
int fib1 = 0, fib2 = 1;
for (int i = 2; i <= count; i++)
{
int next = fib1 + fib2;
// Add statements to print here...
std::cout << std::setw(2) << i;
std::cout << std::setw(14) << next;
std::cout << std::setw(21) << std::setprecision(17) << std::showpoint;
std::cout << static_cast<double>(next) / fib2 << std::endl;
std::cout.unsetf(std::ios_base::showpoint);
fib1 = fib2;
fib2 = next;
}
return;
}
Here's and example. Problems like the Fibonacci are better dealt with recursion. I see that with your do while loops you are trying to use some sort of recursion but it's not really working
int fibonacci(int x)
{
if (x == 0)
return 0;
if (x == 1)
return 1;
return fibonacci(x-1)+fib(x-2);
}
This basically does all you've typed in your main, just supply x and enjoy. Recursion is a difficult concept but once you've got the idea it can preform very effectively but it's pretty limited in my opinion.

Handing over std::vector to function with pointer

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