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.);
Related
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.
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();
}
}
}
}
In the very first example in the boost multi_array documentation, a type for indexing is declared, viz.
typedef boost::multi_array<double, 3> array_type;
typedef array_type::index index;
which can then be used for looping through array indices, e.g.
array_type someArray(boost::extents[3][3][3]);
for(index i = 0; i < 3; i++)
someArray[0][0][i] = i;
This may be a simple question but I cannot find it explicitly documented as to why this index should be used, rather than say an unsigned int.
You cannot generically use an unsigned integer, because the base on certain dimensions could well be negative.
So if you write generic code, you would do best to do infer the index type from the array you're given.
Documentation says
index
This is a signed integral type used for indexing into A. It is also used to represent strides and index bases.
A "correct" index based loop would look similar to:
Live On Coliru
#include <boost/multi_array.hpp>
#include <iostream>
int main() {
using A = boost::multi_array<double, 3>;
A arr(boost::extents[3][2][4]);
std::iota(arr.data(), arr.data()+arr.num_elements(), 1.); // fill with increasing numbers
arr.reindex(-17);
for (A::index i = arr.index_bases()[0]; i < arr.index_bases()[0]+A::index(arr.shape()[0]); ++i) {
for (A::index j = arr.index_bases()[1]; j < arr.index_bases()[1]+A::index(arr.shape()[1]); ++j) {
for (A::index k = arr.index_bases()[2]; k < arr.index_bases()[2]+A::index(arr.shape()[2]); ++k) {
std::cout << "(" << i << "," << j << "," << k << "): " << arr[i][j][k] << "\n";
}
}
}
}
Printing
(-17,-17,-17): 1
(-17,-17,-16): 2
(-17,-17,-15): 3
(-17,-17,-14): 4
(-17,-16,-17): 5
(-17,-16,-16): 6
(-17,-16,-15): 7
(-17,-16,-14): 8
(-16,-17,-17): 9
(-16,-17,-16): 10
(-16,-17,-15): 11
(-16,-17,-14): 12
(-16,-16,-17): 13
(-16,-16,-16): 14
(-16,-16,-15): 15
(-16,-16,-14): 16
(-15,-17,-17): 17
(-15,-17,-16): 18
(-15,-17,-15): 19
(-15,-17,-14): 20
(-15,-16,-17): 21
(-15,-16,-16): 22
(-15,-16,-15): 23
(-15,-16,-14): 24
As part of a program I'm trying to print the contents of an array in reverse order. It is working fine except for one value and I can't figure out why.
I haven't gotten onto functions yet so I haven't used them in my code here is the snippet
case 7:
for (int i = 11; i != -1; i--)// The variable i is initialised to 11. While i is not equal to -1 decrement i by 1.
{
infile >> list[i];//Read in values for array from data.dat
cout << list[i] << " ";// Outputting the array in reverse order.
outfile << "The array in reverse order is: " << list[i] << " " << endl;// Outputting the array in reverse order to file.
}
cout << endl;
break;
The array is filled with the following numbers
8 16 12 6 16 4 8 10 2 16 12 6
The expected output is:
6 12 16 2 10 8 4 16 6 12 16 8
The output I'm getting is:
6 12 16 2 10 8 4 16 6 12 6 8
Any help appreciated
The right way to reverse an iterator is to shift it down by one.
Forward:
T a[N];
for (std::size_t i = 0; i != N; ++i)
{
consume(a[i]);
}
Backward:
T a[N];
for (std::size_t i = 0; i != N; ++i)
{
std::size_t const ri = N - i - 1;
// ^^^
consume(a[ri]);
}
You can write a loop where you actually decrement the loop variable directly, but it's awkward since you either have to use signed integers or otherwise do an additional - 1 when using the index, and it's altogether unnatural, hard to read and easy to get wrong. I'd much rather recommend always using the forward-moving loop as shown here and compute the reverse iterator separately.
Incidentally, this logic is already encapsulated in the iterator wrapper std::reverse_iterator, which is build from a normal, bidirectional moving iterator but decrements by one when being dereferenced. You can either reverse a sequence yourself by using make_reverse_iterator, or by using the free rbegin/rend functions:
#include <iterator>
T a[N];
for (auto rit = std::crbegin(a); rit != std::crend(a); ++rit)
{
consume(*rit);
}
I'm writing a basic chess program to calculate how many sets you can make with the given chess figures. The data file:
4
22 3 5 6 2 0
1 1 1 1 1 1
8 4 4 4 1 2
5 3 3 3 0 2
The code:
#include <iostream>
#include <fstream>
#include <vector>
int main
(int argc, char *argv[])
{
std::fstream data_file;
size_t i, k;
std::vector<long> chess;
long t, n;
data_file.open("U1.txt", std::ios::in);
data_file >> n;
for (i = 0; i < n; i++)
chess.push_back(0);
for (i = 0; i < n; i++) {
for (k = 0; k < 6; k++) {
data_file >> t;
std::cout << t << " ";
chess[k] += t;
}
std::cout << std::endl;
}
data_file.close();
for (int i = 0; i < 6; i++)
std::cout << chess[i] << " ";
std::cout << std::endl;
data_file.open("U1rez.txt", std::ios::out);
data_file << n;
std::cout << n << std::endl;
data_file.close();
return EXIT_SUCCESS;
}
The output:
22 3 5 6 2 0
1 1 1 1 1 1
8 4 4 4 1 2
5 3 3 3 0 2
36 11 13 14 3 4
4
Why am I getting 3 and 4 at the end result just after 36, 11, 13 and 14 at line 5? When I print the test values I seem to get the right numbers but something goes terribly wrong in the addition of them in the vector container.
for (i = 0; i < n; i++)
chess.push_back(0);
.
.
.
for (i = 0; i < n; i++) {
for (k = 0; k < 6; k++) {
data_file >> t;
std::cout << t << " ";
chess[k] += t;
}
std::cout << std::endl;
}
here, you initialized n(=4) places in the vector, but here you are accessing the index 4 and 5 of the vector chess which is causing the addition problem.
On an unrelated note, you will have a much easier time with C++ if you let go of some of the rules imposed by C.
The C++ API uses scope-bounded resource management; i.e. there's no need to explicitly close the file handle here, since the class does this for you when its destructor is called at the end of the declared scope.
Prefer std::cout << "\n" to std::cout << std::endl, unless you actually intend to insert a newline and flush the buffer. Many C++ programmers still use printf, and I personally think that it's a lot more elegant than C++'s ugly standard solution to IO -- feel free to use printf.
Do you find your code easier to manage and read when you declare your variable where they are used (e.g. for (size_type i = 0; ... ; ...)), rather than at the beginning of your method? This also allows the compiler to potentially make better choices about register usage, since it has more information about the scopes of your temporary variables.
Here are a few features of C++11 that can also save you some time:
Automatic type inference: when the compiler can infer the type of a variable, it's not necessary for you to explicitly specify it; you can use auto instead (e.g. auto x = parse_data();).
Range-for: if you are operating on a container that provides global definitions begin() and end() (such as any standard container), then instead of this:
typedef typename container_type::const_iterator iter;
for (iter i = begin(container), iter l = end(container); i != l; ++i) { ... }
You can do this:
for (const auto& x : container) { ... }
I just wanted to give you a few quick pointers that can save you some time.