Trash in operating memory with dynamic arrays - c++

I've tried to make an algorithm, which counts how many numbers are divided without a remainder. Code works, but every time I run it, I'm getting "trash" numbers in my output. I'm using dynamic arrays to solve a problem.
#include <iostream>
using namespace std;
int main()
{
int N = 30;
int *data = new int [N];
for (int i = 0; i < 100; i++)
{
for (int c = 1; c < N; c++)
{
if (i % c == 0)
{
data[c] += 1;
}
}
}
for (int k = 1; k < N; k++)
{
cout << data[k] << endl;
}
delete [] data;
}
I've expected to have, at least, what C++ Shell says: http://cpp.sh/6xtc
100
50
34
25
20
17
15
13
12
10
10
9
8
8
7
7
6
6
6
5
5
5
5
5
4
4
4
4
4
, but got in different IDE the same result:
100
11932994
34
25
20
17
15
13
12
620757039
37045
11951945
8
11927896
7
7
7290
158
6
5
5
570425383
37040
11951941
4
11927892
4
1835102827
859059803

You do
int *data = new int [N];
And allocate an N-sized array. Then you immediately start trying to increment the values in it:
data[c] += 1;
But what was in there to begin with?
If you want to guarantee that all the values will be initialized to 0, per this answer you can allocate your array with:
int *data = new int [N]();
// ^^^^
<Obligatory "you should just be using std::vector!" comment here.\>
(But actually though, vectors would make this way easier and avoid this issue entirely)

data[c] += 1;
You add something to an uninitialized value. data[c] was not necessarily 0 before that. new does not initialize a dynamic array to zero.
Quit all new/delete and use std::vector<>. And, do learn to use the debugger - really helpful in this case.

Related

Why is this code outputting so many numbers? [duplicate]

This question already has answers here:
ARRAYSIZE C++ macro: how does it work?
(7 answers)
c++ sizeof(array) return twice the array's declared length
(6 answers)
Closed 3 years ago.
Starting with two arrays a and b, I am trying to output a matrix c with dimensions sizeof(a) and sizeof(b), whose entries are the product of every pair of the Cartesian product of a and b.
Theses products are also stored in a two dimensional array c.
My code is below.
#include <iostream>
#include <string>
int main()
{
int a[]= { 1,2,3,4,5,5 };
int b[]= { 1,23,2,32,42,4 };
int c[sizeof(a)][sizeof(b)];
for (int i = 0; i < sizeof(a); i++) {
for (int j = 0; j < sizeof(b); j++) {
c[i][j] = a[i]* b[j] ;
std::cout << c[i][j] << " ";
}
std::cout << "\n";
}
return 0;
}
My output is:
1 23 2 32 42 4 -858993460 -858993460 1 2 3 4 5 5 -858993460 16710224 15543422 1 2161328 2122464 16710312 15543008 196436084 15536213
2 46 4 64 84 8 -1717986920 -1717986920 2 4 6 8 10 10 -1717986920 33420448 31086844 2 4322656 4244928 33420624 31086016 392872168 31072426
3 69 6 96 126 12 1717986916 1717986916 3 6 9 12 15 15 1717986916 50130672 46630266 3 6483984 6367392 50130936 46629024 589308252 46608639
...
This is just a small part of the output.
sizeof(a) is not the length of the array, it is the number of bytes required to store it.
Since the element type of the array is larger than one byte each, the numbers are different.

How to read input to a C++ program in reverse order?

Suppose I give input to a C++ program as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
C++ code:
int n;
for (int i = 0; i < 15; i++)
{
std::cin >> n;
// use the value of n to make changes
}
In the above code I can read the input sequentially,
i.e. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15.
Is there any way to read input directly (without using extra memory in C++ program) from the input stream in the following order:
5 4 3 2 1 10 9 8 7 6 15 14 13 12 11
First five digits in reverse order 5 4 3 2 1, next five digits in reverse order 10 9 8 7 6, ...
No.
You need to read the data as they flow into the input stream.
In your program then, you can re-order them in any way you like.
As noted in the comments, the best way to do this is to read them in the order they are given and sort them afterwards.
// vector to hold the values
std::vector<int> values;
values.reserve(15); // reserve for better performance
int n;
for (int i = 0; i < 15; i++)
{
std::cin >> n;
values.push_back(n); // add value to back of vector
}
// sort the vector
std::sort(values.begin(), values.end());
// use the values in ascending order...
for (int i = 0; i < 15; i++) {
std::cout << values[i];
}
Yes this is possible ,but it increase the running time complexity of the code .
First you can make the outer loop for how many series it insert , in the above test case its 3.
Secondly you can make a inner loop which adds the number .
I am not sure the code is running but the logic helps you .
I am implementing the psuedo code using stack !
int n=5;
for(int count = 1 ; count <= 3 ;count++)
{
for(int i=n ; i > n-5 ; i++)
{
push_on_stack(i);
}
n=n+5;
}
You need to wrap your taking input in some functionality that reorders the values for you. You might be able to do so outside the program, i.e., pipe the input stream through another program that reorders the values. Then your code might already work as you have it now.
Or you do this wrapping in your program. For example using a custom stream-like class that buffers the values in between.
There's no way to get this done without using extra memory to buffer the values you don't yet need.
Example:
#include <iostream>
#include <stack>
struct reader {
std::stack<int> data;
reader& operator>>(int & i) {
if (data.empty()) {
while (data.size() < 5) {
data.push(0);
std::cin >> data.top();
}
}
i = data.top();
data.pop();
return *this;
}
explicit operator bool() const { return bool(std::cin); }
};
int main () {
reader r;
int i;
while (r >> i) {
std::cout << i << std::endl;
}
}
Example output:
$ g++ tt.cc -std=c++11 && echo "1 2 3 4 5 6 7 8 9 10" | ./a.out
5
4
3
2
1
10
9
8
7
6
A more straight forward approach would probably be something like this:
#include <iostream>
#include <vector>
int main () {
std::vector<int> buffer;
for (int i; std::cin >> i; ) {
buffer.push_back(i);
if (buffer.size() == 5) {
// do something with buffer
//std::vector<int> reversed(buffer.rbegin(), buffer.rend());
while (!buffer.empty()) {
std::cout << buffer.back() << "\n";
buffer.pop_back();
}
}
}
}

Finding the number of occurences of an integer in multidimensional array in C++

I wish to find the number of occurrences of a number taken as input in the given multidimensional array defined by the logic below:
...
int n,x,count=0;
cin>> n >> x;
int a[n][n] ;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
a[i][j]= i*j ;
}
}
for( int i=1;i<=n;i++)
{
for( int j=1;j<=n;j++)
{
if(a[i][j] == x)
++count;
}
}
cout<< count ;
...
For eg., if I give input as 6(n) and 12(to find its number of occurrences, x here). The multidimensional array looks something like this:
1 2 3 4 5 6
2 4 6 8 10 12
3 6 9 12 15 18
4 8 12 16 20 24
5 10 15 20 25 30
6 12 18 24 30 36
Now, the number of occurences of 12 here is 4(count).
But when I give n as 10 and x as 5, the program stops working. I can't seem to find what is happening. Can someone help me on this?
Also in what way can I modify my code?
How can I handle the case when n is as large as 1000 or 10k without changing the logic of the program?
Indices in C/C++ starts at 0. If an array is declared to have size n as in int a[n] the only valid indices are: 0,1,...,n-1 i.e. [0,n[
If you go out of bound undefined behaviour is expected. That should be your case.
Fix the loops as follows (note the new bounds and the +1 in i and j)
int a[n][n];
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
a[i][j]= (i+1)*(j+1) ;
#include <algorithm>
// ...
for(int i = 0; i < n; ++i) {
count += std::count(a[i], a[i] + n, x);
}
or a more simpler version:
std::cout << std::count(a[0], a[0] + n*n, x);

Printing int **x in GDB

I have an array (called board) of pointers which point to array.
I want to print it in normal way (which is pretty hard in GDB).
int col = 64, row = 2;
int **board = new int*[col];
for(int i = 0; i < col; i++)
board[i] = new int[row];
I have tried following commands:
p *array#len (the problem is it prints in hexadecimal values not as integer)
x/100w array (It scrolls so much down that i cannot even see the values)
*(T (*)[N])p (where p is array, T is type of array and N is size of it) [It just does not print accurate]
I want to print it in normal way
Your best bet is to write a print_board routine, which you can then call from GDB.
(which is pretty hard in GDB).
That's because you made it hard.
The problem is that your board, rather than being contiguous in memory (as is customary and would be trivial to print in GDB), is instead spread out in 64 separate chunks of 2 values each.
Since you are using C++, you'll be better off using a vector of vectors:
vector<vector<int>> board;
board.resize(col);
for (int i = 0; i < col; i++) {
board[i].resize(row);
}
(gdb) print board
$1 = std::vector of length 64, capacity 64 =
{std::vector of length 2, capacity 2 = {0, 0},
std::vector of length 2, capacity 2 = {0, 0},
...
P.S. When asking questions, it helps to show actual code. Your question has the wrong type for board, and mixes board with array.
Update:
How can I do that (use print_board from GDB)?
Here is an example. Suppose your source looks like this:
1 #include <stdio.h>
2
3 int main()
4 {
5 int col = 16, row = 2;
6 int **board = new int*[col];
7
8 for (int i = 0; i < col; i++) {
9 board[i] = new int[row];
10 }
11
12 // Initialize elements to something interesting, so we can see them
13 // printed.
14 for (int i = 0; i < col; i++)
15 for (int j = 0; j < row; j++)
16 board[i][j] = 100*i + j;
17
18 return 0;
19 }
20
21 void print_board(int **board, int col, int row)
22 {
23 for (int j = 0; j < row; j++) {
24 for (int i = 0; i < col; i++) {
25 printf("\t%d", board[i][j]);
26 }
27 printf("\n");
28 }
29 }
Then, using GDB:
gdb -q ./a.out
(gdb) break 18
(gdb) run
Breakpoint 2, main () at t.cc:18
18 return 0;
(gdb) call print_board(board, col, row)
0 100 200 300 400 500 600 700 800 900 1000 1100 1200 1300 1400 1500
1 101 201 301 401 501 601 701 801 901 1001 1101 1201 1301 1401 1501
voilĂ 

C++ passing pointer to vector element instead of array pointer

I think the following code snippet is perfectly legal (it builds anyway on MS Visual Studio 2008, C++).
I use it to link to a 3rd party library. But I think because I am passing a pointer to a vector element instead of a regular pointer that the 3rd party library function expects, I get a run-time error
Invalid parameter detected by C-runtime library
What am I doing wrong here?
std::vector<int> vec_ints(27,0);
std::vector<double> vec_doub(27, 0.);
for(int i = 0; i < n; ++i) {
//-Based on my understanding when i >=27, STL vectors automatically reallocate additional space (twice).
vec_ints[i] = ...;
vec_doub[i] = ...;
}
const int* int_ptr = &vec_ints[0];
const double* doub_ptr = &vec_doub[0];
//-Func is the 3rd party library function that expects a const int* and const double* in the last 2 arguments.
func(...,...,int_ptr,doub_ptr);
But running this after building on MS Visual Studio 2008 (Windows Vista), leads to run-time error as mentioned above, viz.,
Invalid parameter detected by C runtime library
Haven't tested this on Linux yet and I sure would like to avoid copying the contents of the vector into an array just for this. Any ideas what is going on?
Further edit to confirm usage of Nick and Chris' recommendation and to continue discussion with Vlad et al; here's a code snippet:
#include <iostream>
#include <vector>
int main() {
for(int i=2; i<6; ++i) {
int isq = i*i;
std::vector<int> v;
v.reserve(4);
for(int j=0; j<isq; ++j) {
v.push_back(j);
}
std::cout << "Vector v: size = " << v.size() << " capacity = " << v.capacity()
<< "\n";
std::cout << "Elements: \n";
for(int k=0; k<v.size(); ++k) {
std::cout << v.at(k) << " ";
}
std::cout << "\n\n";
}
return 0;
}
Gives output:
Vector v: size = 4 capacity = 4
Elements:
0 1 2 3
Vector v: size = 9 capacity = 16
Elements:
0 1 2 3 4 5 6 7 8
Vector v: size = 16 capacity = 16
Elements:
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
Vector v: size = 25 capacity = 32
Elements:
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
22 23 24
So atleast for the usage in this context, where no explicit resize is used, it seems to work as intended/expected.
std::vector<T> expands if you are adding elements using std::vector<T>::push_back(T &), std::vector<T>::insert(iterator, T &) (thanks K-ballo) or explicitly calling std::vector<T>::resize(size_t). Otherwise, it doesn't expand.
std::vector<int> vec_ints;
vec_ints.reserve(27);
std::vector<double> vec_doub;
vec_doub.reserve(27);
for(int i = 0; i < n; ++i) {
vec_ints.push_back(...);
vec_doub.push_back(...);
}
const int* int_ptr = &vec_ints[0];
const double* doub_ptr = &vec_doub[0];
func(...,...,int_ptr,doub_ptr);
You want something like that
No, vector doesn't expand automatically. You need to expand it yourself:
if (n > 27)
vec_ints.resize(n, 0);
etc.
Why not just create the vectors with the correct size to begin with? Like so:
std::vector<int> vec_ints(n,0);
std::vector<double> vec_doub(n, 0.);