This question already has answers here:
Two different values at the same memory address
(7 answers)
Closed 5 years ago.
New to C++ and learning the const_cast — get really confused by the code below:
int main(){
const int j = 1;
int * p = (int *)(&j);
cout << j << ' ' << *p << endl;
cout << &j << ' ' << p << endl;
*p = 2;
cout << j << ' ' << *p << endl;
cout << &j << ' ' << p << endl;
const int k = 1;
int * q = const_cast<int*>(&k);
cout << k << ' ' << *q << endl;
cout << &k << ' ' << q << endl;
*q = 2;
cout << k << ' ' << *q << endl;
cout << &k << ' ' << q << endl;
return 0;
}
The outputs are
1 1
00A2FD9C 00A2FD9C
1 2
00A2FD9C 00A2FD9C
1 1
00A2FD84 00A2FD84
1 2
00A2FD84 00A2FD84
Could anyone tell me why the addresses (&i and p, or &j and q) are the same, but there values (i and *p, or j and *q) are different? I am using Visual Studio 2013RC.
That happens because the compiler can assume a const variable won't change, and hence when your code refers to it, the compiler assumes that using the variable value, or the original value at initialization won't matter, it shoudn't change behavior, so it compiles to what is faster to execute, just using constant 1 without referring to memory locations.
Using const_cast<T*>(obj) to cast away constness and modifying the object is undefined behavior if obj started its life as a constant. In your example you tell the compiler that j isn't going to change and the compiler just replaces all uses of j to become uses of 1, instead. You then break the promise and the code the compiler generated won't pay any attention to you anymore and, instead, does what it pleases.
Related
I have two double pointer array, which I want to print
but somehow I am not able to do it..
double *noise_feature = new double[5];
double *basic_feature = new double[39];
noise_feature_extraction(sig, len, noise_feature);
basic_feature_extraction(sig, len, basic_feature);
cout << "\n";
printf("Noice features are");
for (auto i = noise_feature.begin(); i != noise_feature.end(); ++i)
cout << *i << " ";
cout << "\n";
printf("Basic features are");
for (auto i = basic_feature.begin(); i != basic_feature.end(); ++i)
cout << *i << " ";
cout << "\n";
This gives error like this
Pan_Tompkins.cpp:992:29: error: member reference base type 'double *' is not a structure or union
for (auto i = noise_feature.begin(); i != noise_feature.end(); ++i)
~~~~~~~~~~~~~^~~~~~
Pan_Tompkins.cpp:992:57: error: member reference base type 'double *' is not a structure or union
for (auto i = noise_feature.begin(); i != noise_feature.end(); ++i)
I tried printing this way
printf("%g",noise_feature);
printf("%g",basic_feature);
This does not give error but also does not print anything.
How can I print this two double array to see their value?
You request a raw array on the heap and discard the info how many elements it has. Recall that
double *noise_feature = new double[5];
declares nothing but a pointer to double. The fact that you know it's a contiguous array of length 5 can be used in different way. Either you keep that magic number literal in your code;
for (auto value = noise_feature; value != noise_feature + 5; ++value)
// not maintainable, but works: ^^^^^^^^^^^^^^^^^
cout << *value << " ";
Or you go with a raw array on the stack. Here, the length is baked into the type and hence not lost. You could use a range-based for loop to iterate over it, for example.
double noise_features[5];
// ...
for (double value : noise_features)
std::cout << value << ' ';
However, the preferred solution is using either std::vector if the size of your sequence is only known at runtime, or std::array if it's a fixed-length sequence.
You declared two pointers
double *noise_feature = new double[5];
double *basic_feature = new double[39];
Pointers are scalar objects that do not have the member functions begin and end.
So you have to use the magic numbers 5 and 39 to output the allocated arrays pointed to by the pointers.
For example
cout << "\n";
printf("Noice features are");
for ( size_t i = 0; i < 5; ++i )
cout << noise_feature[i] << " ";
cout << "\n";
printf("Basic features are");
for ( size_t i = 0; i < 39; ++i )
cout << basic_feature[i] << " ";
cout << "\n";
The same can be done using pointers as for example
cout << "\n";
printf("Noice features are");
for ( auto p = noise_feature; p != noise_feature + 5; ++p )
cout << *p << " ";
cout << "\n";
printf("Basic features are");
for ( auto p = basic_feature; p != basic_feature + 39; ++p )
cout << *p << " ";
cout << "\n";
Pay attention to that instead of "manually" allocating dynamically arrays you could use the standard container std::vector as for example
#include <vector>
//...
std::vector<double> noise_feature( 5 );
//...
cout << "\n";
printf("Noice features are");
for ( const auto &item : noise_feature )
cout << item << " ";
cout << "\n";
//...
Arrays defined with statements like array_name[element_count] are not objects of any class!
Arrays are actually pointers to continuous memory. So, they don't have any methods and member functions. So your code will fail to compile. So instead of this:
for (auto i = noise_feature.begin(); i != noise_feature.end(); ++i)
Use this:
for (auto i = noise_feature; i != noise_feature + 5; ++i)
Or this:
for (auto i = std::begin(noise_feature); i != std::end(noise_feature); ++i)
Or you can store it in a std::vector<double> object. Also, why you used printf when C++ provides std::cout ?
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.
Here's the code:
#include "stdafx.h"
#include <iostream>
using namespace std;
int main()
{
int keyArray[7] = {1,2,3,4,5,6,7};
int breakPoint;
int counter;
for (counter = 0; counter < 7; counter++)
{
// keyArray[counter] = (rand() % 9) + 1; later
keyArray[counter] = counter; //testing
}
cout << keyArray[0] + "\n";
cout << keyArray[1] + "\n";
cout << keyArray[2] + "\n";
cout << keyArray[3] + "\n";
cout << keyArray[4] + "\n";
cout << keyArray[5] + "\n";
cout << keyArray[6] + "\n";
cin >> breakPoint; //so I can see what the hell is going on before it disappears
return 0;
}
The only reason I gave values to keyArray was that I read in answer to a similar question that you have to initialize an array with data before you use it. But it made no difference. The output is just junk symbols whether you initialize or not.
The compiler is Visual Studio Community 2017. Thanks for any help.
The error is not in your logic but rather in your debugging output. Since the other answers focus on how to fix it, I'll rather explain what happens instead. There seems to be a misunderstanding about the way strings work in C++.
The failure is in this operation:
keyArray[0] + "\n"
Internally, string literals are arrays of characters, in this case const char[2], consisting of the newline and a terminating '\0' null terminator. When you then try to add the integer and this array together, the array will be represented by a pointer to its first element, i.e. it will decay to const char* in order to be used as the second argument to the plus operator used in your code.
So for the compiler, this line will need operator+(int, const char*). But the result of that will be const char*, the input pointer offset by the integer, as that is the operation that happens when adding integers to pointers.
So instead of printing the number and then the string, it will try to access a string that does not exist as the pointer now pointer behind the string "\n" and thus into some arbitrary memory.
Instead of doing
cout << keyArray[0] + "\n"
do:
cout << keyArray[0] << "\n"
or
cout << keyArray[0] << endl
You can't concatanate an integer with a string. That's why you got garbage output
Try this first:
cout << keyArray[0] << "\n";
If you are using compilers that support C++ 11 then try using std::to_string(...) to make a string from an integer before doing the addition:
cout << (std::to_string(keyArray[0]) + "\n");
you cannot concatenate int with string.
change
cout << keyArray[0] + "\n";
cout << keyArray[1] + "\n";
cout << keyArray[2] + "\n";
cout << keyArray[3] + "\n";
cout << keyArray[4] + "\n";
cout << keyArray[5] + "\n";
cout << keyArray[6] + "\n";
to
cout << keyArray[0] << "\n"
<< keyArray[1] << "\n"
<< keyArray[2] << "\n"
<< keyArray[3] << "\n"
<< keyArray[4] << "\n"
<< keyArray[5] << "\n"
<< keyArray[6] << endl;
You need to convert the integers into a string. Using a relatively recent version of C++:
#include "stdafx.h"
#include <iostream>
using namespace std;
int main()
{
int keyArray[7] = {1,2,3,4,5,6,7};
int breakPoint;
int counter;
for (counter = 0; counter < 7; counter++)
{
// keyArray[counter] = (rand() % 9) + 1; later
keyArray[counter] = counter; //testing
}
cout << std::to_string(keyArray[0]) + "\n";
cout << std::to_string(keyArray[1]) + "\n";
cout << std::to_string(keyArray[2]) + "\n";
cout << std::to_string(keyArray[3]) + "\n";
cout << std::to_string(keyArray[4]) + "\n";
cout << std::to_string(keyArray[5]) + "\n";
cout << std::to_string(keyArray[6]) + "\n";
cin >> breakPoint; //so I can see what the hell is going on before it disappears
return 0;
}
I'm trying to write a program that reads values from cin using a pointer, and then outputs the values alongside their position in the array. I can't figure out why printNumbers1 works but printNumbers2 doesn't. Here is the program (relevant code near the bottom):
#include <iostream>
using namespace std;
int *readNumbers(int);
void printNumbers1(int*);
void printNumbers2(int*);
int main()
{
int *numbers = readNumbers(5);
printNumbers1(numbers);
printNumbers2(numbers);
return 0;
}
int *readNumbers(int n)
{
int a[n];
int *numbers;
numbers = &a[0];
for (int i=0; i<n; i++)
{
cin >> *(numbers+i);
}
return numbers;
}
void printNumbers1(int *numbers)
{
cout << 0 << ' ' << *(numbers) << endl
<< 1 << ' ' << *(numbers+1) << endl
<< 2 << ' ' << *(numbers+2) << endl
<< 3 << ' ' << *(numbers+3) << endl
<< 4 << ' ' << *(numbers+4) << endl;
}
void printNumbers2(int *numbers)
{
for (int i=0; i<5; i++)
{
cout << i << ' ' << *(numbers+i) << endl;
}
}
When I run the program, it works as intended for printNumbers1 but outputs a combination of seemingly random numbers and 0s for printNumbers2. I feel like the two printNumbers functions should should function identically, but they don't. What am I missing?
This happens because of a combination of two things:
C++ does not allow variable-length arrays - this is a popular extension, but the declaration int a[n] is not standard.
You cannot return a pointer to local variable from a function - pointer numbers inside readNumbers points to a, a local variable. You can use this pointer inside the function, but outside of the function it becomes invalid, because a goes out of scope.
Using an out-of-scope variable causes undefined behavior. This Q&A provides a very good explanation of what is happening, and why it may look like the program is working fine.
If you want to use built-in pointers, remove int a[n], and change the declaration of numbers as follows:
int *numbers = new int[n];
You also need to add
delete[] numbers;
before return 0 line to avoid memory leaks.
I am assuming that you wrote this code as part of a learning exercise. In general, though, a better approach in C++ is to use std::vector<int>, which hides pointer operations from your code, and deals with resource management for you.
readNumbers returns a pointer to a variable with automatic storage duration.
The behaviour on dereferencing that pointer is undefined.
Use a std::vector instead. Rely on return value optimisation to obviate any superfluous value copies being taken.
Here you have created the array a[n] inside the function, so it is a local variable, Hence this array may or may not be deleted after the scope of the function ends.Never use the address of a local variable outside the funcrtion. This code is working:
#include <iostream>
using namespace std;
int *readNumbers(int);
void printNumbers1(int*);
void printNumbers2(int*);
int main()
{
int *numbers = readNumbers(5);
printNumbers1(numbers);
printNumbers2(numbers);
return 0;
}
int *numbers;
int *readNumbers(int n)
{
numbers = new int[n];
for (int i=0; i<n; i++)
{
cin >> *(numbers+i);
}
return numbers;
}
void printNumbers1(int *numbers)
{
cout << 0 << ' ' << *(numbers) << endl
<< 1 << ' ' << *(numbers+1) << endl
<< 2 << ' ' << *(numbers+2) << endl
<< 3 << ' ' << *(numbers+3) << endl
<< 4 << ' ' << *(numbers+4) << endl;
}
void printNumbers2(int *numbers)
{
for (int i=0; i<5; i++)
{
cout << i << ' ' << *(numbers+i) << endl;
}
}
This question already has answers here:
Undefined behavior and sequence points
(5 answers)
Closed 5 years ago.
When using a single cout to print the same variable updated multiple times, I am getting a weird order of updates. Can anybody explain how such updates are done?
int value = 2;
cout << value << value++ << ++value << endl; // 434
value = 2;
cout << ++value << value++ << value << endl; // 424
value = 2;
cout << value++ << value++ << ++value << endl; // 435
value = 2;
cout << ++value << value++ << value++ << endl; // 532
The order in which expressions in a single statement are executed is undefined. Obviously unless specified via parenthesis or rules of order of execution. For example:
int a[3]{};
int i=1;
a[i] = i++; //undefined if a[1] or a[2]
Behaviour of such code is not defined and depends on compiler and platform in use. Needless to say you should not rely on a certain behaviour of this code.