C++ Program Apparently Printing Memory Address instead of Array - c++

#include <iostream>
using namespace std;
int main(){
int findMax(int *);
const int MAX = 100;
int values[MAX];
char ivals[256];
// Get the space-separated values from user input.
cin.getline(ivals, 256, '0');
char *helper;
// Clean input array and transfer it to values.
for(int i = 0; i < (MAX) && ivals[i] != 0; i++){
helper = ivals[i * 2];
values[i] = atoi(helper);
}
int mval = findMax(values);
cout << values << endl << mval;
return 0;
}
//Function to find the maximum value in the array
int findMax(int arr[]){
int localmax = 0;
for(int i = 0; i < (sizeof(arr)/sizeof(int)); i++){
if(arr[i] > localmax){
localmax = arr[i];
}
}
return localmax;
}
The purpose of this program is for the user to input a space-separated series of values ended by a 0. That array is then to be analyzed to find the max. I figured out how to convert what is originally a char[] into an int[] so that I can use the findMax() function on it without error but the sorting loop seems to have a problem of its own and when "cout << values << endl << mval;" is called, it returns only a memory address instead of what should be a non-spaced sequence of ints. Can anybody explain what I am doing wrong? It seems that I may have made some mistake using the pointers but I cannot figure out what.

Printing values won't print the contents of the array as you expect, it will print the memory location of the first element of the array.
Try something like this instead:
#include <iterator>
#include <algorithm>
// ...
copy(&values[0], &values[MAX], ostream_iterator(cout, " "));
Sorry I can't post actual working code, but your original post is a mess with many syntax and syntactic errors.
EDIT: In the interest of being more complete and more approachable & understandable to beginners, I've written a small program that illustrates 4 ways to accomplish this.
Method 1 uses copy with an ostream_iterator as I've done above.
Method 2 below is probably the most basic & easiest to understand.
Method 3 is a C++0x method. I know the question is tagged C++, but I thought it might be educational to add this.
Method 4 is a C++ approach using a vector and for_each. I've implemented a functor that does the dumping.
Share & Enjoy
#include <iostream>
#include <iterator>
#include <algorithm>
#include <functional>
#include <vector>
using namespace std;
struct dump_val : public unary_function<int,void>
{
void operator()(int val)
{
cout << val << " ";
}
};
int main(){
int vals[5] = {1,2,3,4,5};
// version 1, using std::copy and ostream_iterator
copy(&vals[0], &vals[5], ostream_iterator<int>(cout, " "));
cout << endl;
// version 2, using a simple hand-written loop
for( size_t i = 0; i < 5; ++i )
cout << vals[i] << " ";
cout << endl;
// version 3, using C++0x lambdas
for_each(&vals[0], &vals[5], [](int val)
{
cout << val << " ";
}
);
cout << endl;
// version 4, with elements in a vector and calling a functor from for_each
vector<int> vals_vec;
vals_vec.push_back(1);
vals_vec.push_back(2);
vals_vec.push_back(3);
vals_vec.push_back(4);
vals_vec.push_back(5);
for_each( vals_vec.begin(), vals_vec.end(), dump_val() );
cout << endl;
}

When you pass around an array of X it's really a pointer to an array of X that you're passing around. So when you pass values to cout it only has the pointer to print out.
You really should look into using some of the standard algorithms to make your life simpler.
For example to print all the elements in an array you can just write
std::copy(values, values+MAX, std::ostream_iterator<int>(std::cout, "\n"));
To find the max element you could just write
int mval = *std::max_element(values, values+MAX);
So your code becomes
#include <iostream>
using namespace std;
int main(){
const int MAX = 100;
int values[MAX];
char ivals[256];
// Get the space-separated values from user input.
cin.getline(ivals, 256, '0');
char *helper;
// Clean input array and transfer it to values.
for(int i = 0; i < (MAX) && ivals[i] != 0; i++){
helper = ivals[i * 2];
values[i] = atoi(helper);
}
copy(values, values+MAX, ostream_iterator<int>(cout, "\n"));
cout << *std::max_element(values, values+MAX);
return 0;
}
Doing this removes the need for your findMax method altogether.
I'd also re-write your code so that you use a vector instead of an array. This makes your code even shorter. And you can use stringstream to convert strings to numbers.
Something like this should work and is a lot less code than the original.
int main(){
vector<int> values;
char ivals[256];
// Get the space-separated values from user input.
cin.getline(ivals, 256, '0');
int temp = 0;
stringstream ss(ivals);
//read the next int out of the stream and put it in temp
while(ss >> temp) {
//add temp to the vector of ints
values.push_back(temp);
}
copy(values.begin(), values.end(), ostream_iterator<int>(cout, "\n"));
cout << *std::max_element(values.begin(), values.end());
return 0;
}

Array of int is promoted to a pointer to int when passed to a function. There is no operator << taking ordinary array. If you want to use operator << this way, you need to use std::vector instead.
Note: it is possible technically to distinguish array when passed to a function using template, but this is not implemented for standard operator <<.

for(int i = 0; i < (sizeof(arr)/sizeof(int)); i++){
sizeof(arr) here is the size of the pointer to the array. C++ will not pass the actual array, that would be grossly inefficient. You'd typically only get one pass through the loop. Declare your function like this:
int findMax(int* arr, size_t elements) {
//...
}
But, really, use a vector.
Oh, hang on, the question. Loop through the array and print each individual element.

Related

C++ pointers not accessing correct memory address, instead accessing random memory locations

I'm learning C++ and I'm wondering if anyone can explain some strange behaviour I'm seeing.
I'm currently learning memory management and have been playing around with the following code:
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
// pass back by pointer (old C++)
const int array_size = 1e6; // determines size of the random number array
vector<int> *RandomNumbers1()
{
vector<int> *random_numbers = new vector<int>[array_size]; // allocate memory on the heap...
for (int i = 0; i < array_size; i++)
{
int b = rand();
(*random_numbers).push_back(b); // ...and fill it with random numbers
}
return random_numbers; // return pointer to heap memory
}
int main (){
vector<int> *random_numbers = RandomNumbers1();
for (int i = 0; i < (*random_numbers).size(); i++){
cout << (*random_numbers)[i] + "\n";
}
delete random_numbers;
}
What I'm trying to do is get a pointer to a vector containing random integers by calling the RandomNumbers1() function, and then print each random number on a new line.
However, when I run the above code, instead of printing out a random number, I get all sorts of random information. It seems as though the code is accessing random places in memory and printing out the contents.
Now I know that I'm doing something stupid here - I have an int and I am adding the string "\n" to it. If I change the code in main() to the following, it works fine:
int main (){
vector<int> *random_numbers = RandomNumbers1();
for (int i = 0; i < (*random_numbers).size(); i++){
cout << to_string((*random_numbers)[i]) + "\n";
}
}
However I just can't understand the behaviour I'm getting with the "wrong" code - i.e. how adding the string "\n" to (*random_numbers)[i]
causes the program to access random areas of memory, instead of where my pointer is pointing to. Surely I have de-referenced the pointer and accessed the element at position i before "adding" "\n" to it? So how is the program instead accessing a totally different memory address?
"\n" is a string literal. It is an array and it is converted to a pointer pointing at its first element in your expression.
(*random_numbers)[i] is an integer.
Adding a pointer to an integer means that advance the pointer by the integer.
This will drive the pointer to out-of-range because "\n" has only 2 elements ('\n' and '\0') but the numbers returnd from the rand() function are likely to be larger than 2.
There are several issues with your code.
you are using delete instead of delete[] to free the array allocated with new[].
you are creating an array of 1000000 vectors, but populating only the 1st vector with 1000000 integers. You probably meant to create just 1 vector instead.
you can and should use the -> operator when accessing an object's members via a pointer. Using the * and . operators will also work, but is more verbose and harder to read/code for.
you are trying to print a "\n" after each number, but you are using the + operator when you should be using the << operator instead. You can't append a string literal to an integer (well, you can, but it will invoke pointer arithmetic and thus the result will not be what you want, as you have seen).
With that said, try something more like this:
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
const int array_size = 1e6; // determines size of the random number array
vector<int>* RandomNumbers1()
{
vector<int> *random_numbers = new vector<int>;
random_numbers->reserve(array_size);
for (int i = 0; i < array_size; ++i)
{
int b = rand();
random_numbers->push_back(b);
}
return random_numbers;
}
int main (){
vector<int> *random_numbers = RandomNumbers1();
for (size_t i = 0; i < random_numbers->size(); ++i){
cout << (*random_numbers)[i] << "\n";
}
/* alternatively:
for (int number : *random_numbers){
cout << number << "\n";
}
*/
delete[] random_numbers;
}
However, if you are going to return a pointer to dynamic memory, you really should wrap it inside a smart pointer like std::unique_ptr or std::shared_ptr, and let it deal with the delete for you:
#include <iostream>
#include <vector>
#include <cmath>
#include <memory>
using namespace std;
const int array_size = 1e6; // determines size of the random number array
unique_ptr<vector<int>> RandomNumbers1()
{
auto random_numbers = make_unique<vector<int>>();
// or: unique_ptr<vector<int>> random_numbers(new vector<int>);
random_numbers->reserve(array_size);
for (int i = 0; i < array_size; ++i)
{
int b = rand();
random_numbers->push_back(b);
}
return random_numbers;
}
int main (){
auto random_numbers = RandomNumbers1();
for (size_t i = 0; i < random_numbers->size(); ++i){
cout << (*random_numbers)[i] << "\n";
}
/* alternatively:
for (int number : *random_numbers){
cout << number << "\n";
}
*/
}
Though, in this case, there is really no good reason to create the vector dynamically at all. 99% of the time, it is unnecessary and unwanted to use standard containers like that. Since the vector manages dynamic memory internally, there is no reason for the vector itself to also be created in dynamic memory. Return the vector by value instead, and let the compiler optimize the return for you.
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
const int array_size = 1e6; // determines size of the random number array
vector<int> RandomNumbers1()
{
vector<int> random_numbers;
random_numbers.reserve(array_size);
for (int i = 0; i < array_size; ++i)
{
int b = rand();
random_numbers.push_back(b);
}
return random_numbers;
}
int main (){
vector<int> random_numbers = RandomNumbers1();
for (size_t i = 0; i < random_numbers.size(); ++i){
cout << random_numbers[i] << "\n";
}
/* alternatively:
for (int number : random_numbers){
cout << number << "\n";
}
*/
}

Get number of same values in arrays in C++

I need a function int countDifferentNumbers(int v[], int n) which counts how many different values the array v with n entries contains.
Example:
It should return the result 3 for the array v = {1, 5, 5, 8, 1, 1} because the array contains only 3 different values.
This is how the code looks like so far:
int countDifferentNumbers(int v[], int n)
{
int counter = 0;
for(int i = 0; i < n; ++i)
{
for(int j = i; j < n; ++j)
{
if(v[i] == v[j + 1])
{
cout << "match" << endl;
counter++;
cout << v[i] << endl;
}
}
}
return counter;
}
I would appreciate an explanation of what is wrong in my function and how I need to redesign it.
Note: Unfortunately, I have not found a suitable thread for this either. All threads with my problems were solved in Java and Python languages.
Recently I see more and more answers here on SO that lead users in the wrong direction by giving bad answers.
Also, for C++, the question has already been answered in the comment by Igor Tandetnik, and that should finally be used.
But let me answer the question of the OP as asked. What is wrong with my function? OK, there are several aspects. Let us first look at the style.
You have 0 lines of comments, so the code quality is 0. If you would write comments, then you would already find most bugs by yourself, because then, you need to explain your own wrong statements.
Then please see your source code with my amendments. I added the problems as comment.
// This is just a dumped function and not a minimum reproducible example
// All header files are messing
// Obviously "using namespace std;" was used that should NEVER be done
// The function should retrun an unsigned value, best size_t, because a count can never be negative
// Same for n, that is the size of an array. Can also never be negative
// C-sytle arrays should NEVER be used in C++. NEVER. Use std::vector or std::array instead
int countDifferentNumbers(int v[], int n)
{
int counter = 0; // Now in C++ we can use braced initialzation instead of assignement
for (int i = 0; i < n; ++i)
{
for (int j = i; j < n; ++j)
{
if (v[i] == v[j + 1]) // Accessing out of bounds element
{
cout << "match" << endl; // Now endl needed here. Can all be done in one cout statement in one line
counter++; // Always counting up the same counter for all kind of double numbers.
cout << v[i] << endl;
}
}
}
return counter;
That was one point of the answer. But now the second point. Evene more important. The algorithm or the design is wrong. And finding the correct solution, this thinking before codingt, you need to do, before you write any line of code.
You obviously want to find the count of unique numbers in an array.
Then you could look what is already there on Stackoverflow. You would probaly find 20 answers already that coud give you a hint.
You could use std::unique. Please see here for a description. This function sounds like it does what you want, right? Some example implementation:
#include <iostream>
#include <unordered_map>
#include <vector>
#include <algorithm>
// If you want to keep the original data, remove the reference-specifier &
size_t countDifferentNumbers(std::vector<int>& v) {
std::sort(v.begin(), v.end()); // Sorting is precondition for std::unique
v.erase(std::unique(v.begin(), v.end()), v.end()); // Erase all non-unique elements
return v.size(); // Return the result
}
int main() {
std::vector test{ 1, 5, 5, 8, 1, 1 }; // Some test data
std::cout << countDifferentNumbers(test) << '\n'; // SHow result to user
return 0;
}
Then, we could count the occurence of each number in a std::map or std::unordered_map. And the number of counters will be the result. Example:
#include <iostream>
#include <unordered_map>
#include <vector>
#include <algorithm>
// If you want to keep the original data, remove the reference-specifier &
size_t countDifferentNumbers(std::vector<int>& v) {
std::unordered_map<int, size_t> counter{}; // Here we will count all occurences of different numbers
for (const int i : v) counter[i]++; // Iterate over vector and count different numbers
return counter.size(); // Count of different numbers
}
int main() {
std::vector test{ 1, 5, 5, 8, 1, 1 }; // Some test data
std::cout << countDifferentNumbers(test) << '\n'; // Show result to user
return 0;
}
But, then, thinking further, about what conatiners we could use, we will find out the answer from Igor Tandetnik. There are 2 containers that can hold unique values only. No double values. And these are: std::set and std::unordered_set., So, we can simply copy the data into one of those containers, and, only unique values will be stored there.
There are many ways to get the data into a set. But the simplest one is to use its range constructor. Then, we have unique elements, and, the containers size function will give the result:
See here: Constructor Number 2.
The result will be a function with one line like this
#include <iostream>
#include <unordered_set>
#include <vector>
// If you want to keep the original data, remove the reference-specifier &
size_t countDifferentNumbers(std::vector<int>& v) {
return std::unordered_set<int>(v.begin(), v.end()).size();
}
int main() {
std::vector test{ 1, 5, 5, 8, 1, 1 }; // Some test data
std::cout << countDifferentNumbers(test) << '\n'; // Show result to user
return 0;
}
And since functions with one line are often not so usefull, we can also write the final solution:
#include <iostream>
#include <unordered_set>
#include <vector>
int main() {
std::vector test{ 1, 5, 5, 8, 1, 1 }; // Some test data
std::cout << std::unordered_set<int>(test.begin(), test.end()).size() << '\n'; // Show result to user
return 0;
}
So, by analyzing the problem and choosing the right algorithm and container and using C++, we come to the most easy solution.
Please enable C++17 for your compiler.
first sort the array v. if n >0 then initially there must be one number which is unique so just increment the value of counter once. then with loop check if the two consecutive number are same or not. if same do nothing else increment the value of counter.
if you are writing code in c then use qsort. #include <stdlib.h> add this in header and. use qsort() func
here is the code:
#include <bits/stdc++.h>
using namespace std;
int countDifferentNumbers(int v[] , int n)
{
int counter = 0;
sort(v, v+ n); // if you are writing code in c then just write a decent sort algorithm.
if (n>0 ){
printf("%d\n", v[0]);
counter ++;
}
for(int i = 0; i < n-1; ++i)
{
if(v[i] == v[i+1]){
continue;
} else {
printf("%d\n", v[i+1]);
counter++;
}
}
return counter;
}
int main()
{
int v[] = {1, 5, 5, 8, 1, 1};
int result = countDifferentNumbers(v,6);
printf("unique number %d", result );
return 0;
}

Append data to array in C++

double b[3] = {3,3,4};
for(int i=0;i<3;i++) {
cout<<b[i]<<" "<<endl;
}
int sum = 0;
for(int i=0;i<3;i++) {
sum += b[i];
} cout<<"\n"<<sum<<endl;
for(int i=0;i<3;i++) {
double norm_b = b[i]/sum;
cout<<norm_b<<endl;
}
Result:
0.3
0.3
0.4
How to insert data (norm_b) to array, like append in Python?
The size of an array never changes through its lifetime. As such, there is no way to insert (nor to remove) elements.
What can be done instead, is to allocate an array dynamically, and upon insertion, allocate a bigger array, copy the elements from the old one, which can then be deallocated - or at least that is the general idea; I've skipped implementation details. Such data structure is called a resizable array. The standard library has an implementation of the resizable array: std::vector.
Because you mention Python, then there are better library classes and algorithms that are closer to what you might be used from Python.
#include <vector>
#include <algorithm>
#include <numeric>
void main() {
std::vector<double> b{3, 3, 4}; // Init vector
// If compiler supports C++11 you can use range-for
for (auto value : b)
{
std::cout << value << " " << std::endl;
}
double sum = std::accumulate(b.begin(), b.end(), 0); // sum b, sum should be double, not int?
std::cout << "\n"
<< sum << std::endl;
std::vector<double> norm_b(b.size()); // initialize norm_b with b.size() elements
size_t idx = 0;
std::generate(norm_b.begin(), norm_b.end(), [&b, &idx, &sum]() {
return b[idx++] / sum;
});
// Again range-for if C++11
for (auto value : norm_b)
{
std::cout << value << " " << std::endl;
}
}
There are a number of things in this code that you should look up if you don't fully understand:
Various way to initiliaze a std::vector (initializer list - braced initialization, count constructor etc)
std::vector iterators
std::accumulate
std::generate
lambdas
range-for
iterators based for (not used in the code above)
You can "append" a value only to a data structure that can dynamically grow in size. A c-like array if fixed size. You can try to use a std::vectorwhich has a push_back method, equivalent to python append method.
note: Instead of C-like array, consider to use std::array which is part of c++ STL and let you use STL algorithm on it.
Thank you guys
Solved
Update:
#include <vector>
vector<double> vec;
for(int i=0;i<3;i++) {
vec.push_back(b[i]/sum);
cout<<vec[i]<<endl;
}
you can use vector for append data as more as you like.For use vector you have to include a header file name vector.Here the code below:
#include<iostream>
#include<vector>
using namespace std;
int main()
{
//declare a vector first
vector<double>v;
int sum = 0;
for(int i=0;i<3;i++)
{
sum += b[i];
}
for(int i=0;i<3;i++)
{
vec.push_back(b[i]/sum);
cout<<vec[i]<<" "<<endl;
}
return 0;
}

How can I print the numbers in main function?

I am new to c++ language. I am trying to solve a problem using function. I have to print the pentagon numbers untill the integer input, but when function returns the values, it only prints one value. I would love some help with it.
#include<iostream>
using namespace std;
int pent(int num){
int p;
for(int i=1;i<=num;i++){
p=(i*(3*i-1)/2);
}
return p;
}
int main(){
int num;
cin>>num;
int sender=pent(num);
cout<<sender<<endl;
return 0;
}
Your function returns int, that is a single integer. To return more, you can use std::vector. As you probably are not familiar with it, I will give you some pointers...
The most simple constructor creates a vector with no entries:
std::vector<int> x;
You can reserve space for elements via reserve:
x.reserve(num);
The vector still has no elements, but it already allocated enough space to hold num elements. This is important, because when we will add elements the vector will grow and that potentially requires to copy all elements to a different place in memory. We can avoid such frequent reallocations by reserving enough space upfront.
To add elements to the vector you can use push_back:
x.push_back(42);
Eventually to print all elements of the vector we can use a range-based for loop:
for (auto element : x) std::cout << element << " ";
So you can rewrite your code like this:
#include <iostream>
#include <vector>
std::vector<int> pent(int num){
std::vector<int> result;
result.reserve(num);
for(int i=1;i<=num;i++){
result.push_back(i*(3*i-1)/2);
}
return result;
}
int main(){
int num;
std::cin >> num;
auto sender = pent(num);
for (auto number : sender) std::cout << number << " ";
}
In your program, from your pent() function you are only returning last calculated value. In you ever time, you are overwriting you variable p.
So there is a way which #asmmo is suggesting, to print in pent() function.
Or you can pass a vector to your pent() function and store values in that and print it in main function.
For your ref:
void pent(int num, vector<int> &arr) {
int p;
for (int i = 1; i <= num; i++) {
arr[i-1] = (i*(3 * i - 1) / 2);
}
}
int main() {
int num;
cin >> num;
vector<int> arr(num);
pent(num, arr);
for (int i = 0; i < num; i++) {
cout << arr[i] << endl;
}
return 0;
}

Sorting a vector of structs in C++

I have a problem. The statement says that the results at a contest are read from standard input and I have to print to the screen the final standings in decreasing order by the number of solved problems. Here is my code.
#include <cstdio>
#include <vector>
#include <cstdlib>
using namespace std;
struct results
{
unsigned int id; //id of the team
unsigned int m; //number of solved problems
};
int comparare(const void * i, const void * j) //compare function for qsort()
{
return -( *(unsigned int*)i - *(unsigned int*)j );
}
int main()
{
unsigned int n;
vector<results> standings; //initializing an array of structs
scanf("%u", &n); //the size of the vector
for(unsigned int i=0; i<n; ++i)
{
scanf("%u%u", &standings[i].id, &standings[i].m); //reading the elements
standings.push_back(results());
}
qsort(standings, n, sizeof(results), comparare); //sorting the array
for(unsigned int i=0; i<n; ++i)
printf("%u %u\n", standings[i].id, standings[i].m); //print the sorted array
return 0;
}
When I want to compile the code, the compiler finds the error
cannot convert 'std::vector' to 'void*' for argument '1' to 'void qsort(void*, size_t, size_t, __compar_fn_t)'
in the line qsort(standings, n, sizeof(results), comparare);
What I have to do to repair this?
If you absolutely must use qsort on a vector (and you don't. And shouldn't), then you have to pass it like this:
qsort(standings.data(), standings.size(), sizeof(results), comparare);
vector::data fetches a pointer to the array stored in the vector. Simply passing a pointer to the vector itself will not help.
Note that vector::data requires C++11; use &vector[0] if data is not available to you.
But really, just use std::sort:
std::sort(standings.begin(), standings.end(), [](const results &lhs, const results &rhs) {return lhs.id < rhs.id;});
Obviously the lambda requires C++11; feel free to use a namespace-declared struct for earlier C++ versions.
You're using C constructs, but should be using more C++ constructs. std::sort is faster than qsort generally and it's usage is much more intuitive. Here's how you can rewrite it without C++11.
#include <iostream>
#include <vector>
#include <algorithm>
struct results {
unsigned int id; //id of the team
unsigned int m; //number of solved problems
};
// I guess you're trying to sort on number of solved problems. If not, change `.m` to `.id`
bool comparare(const results lhs, const results rhs) {
return lhs.m > rhs.m;
}
int main() {
size_t n;
std::cout << "Enter number of results: " << std::endl;
std::cin >> n;
std::vector<results> standings(n); // Creates std::vector of results with n elements
// read in id and number of problems solved
for(size_t i=0; i < n; ++i) {
std::cin >> standings[i].id >> standings[i].m;
}
// sort the array
std::sort(standings.begin(), standings.end(), comparare);
// output the sorted array's id
for(size_t i = 0; i < standings.size(); ++i) {
std::cout << "In " << i+1 << " place: " << standings[i].id << " with " << standings[i].m << " problems solved." << std::endl;
}
return 0;
}
Here's the ideone with an example.
Your comparison function comparare is not appropriate if the values can exceed INT_MAX. For example comparing UINT_MAX and 0 will cause an overflow when returning UINT_MAX - 0 as an int. It is undefined behavior and on common platforms it will actually be negative.
Use this comparison function instead:
//compare function for qsort()
int comparare(const void *i, const void *j) {
unsigned int ni = *(unsigned int*)i;
unsigned int nj = *(unsigned int*)j;
return (ni > nj) - (ni < nj);
}
It returns -1, 0 or 1 if *i is respectively smaller than, equal to or greater than *j.
In C++ there are other more idiomatic ways to sort an array.