Create a list of pointers to random generated int - c++

I'm having some difficulty in generating a random int* and store it into a list<int*>.
I have tried the following:
std::list<int*> generateInt(){
std::list<int*> randomInt;
int i = 0;
// initialize random seed
srand (time(NULL));
while (i < 5){
int* random = (int*)std::rand();
std::cout << "Random int generated: " << random << std::endl;
randomInt.push_back(random);
i++;
}
return randomInt;
}
But I get compiler issue as following
error: cast to pointer from integer of different size [-Werror=int-to-pointer-cast]
int* random = (int*)std::rand();
^
I'm not sure if i'm missing something important here?
Any help or advice would be very appreciated. Thanks!

The easiest way I can think of is:
std::vector<int> generateInt(){
std::vector<int> randomInt;
int i = 0;
// initialize random seed
// srand (time(NULL)); Let that be the first line in main()
while (i < 5){
int random = std::rand();
std::cout << "Random int generated: " << random << std::endl;
randomInt.push_back(random);
i++;
}
return randomInt;
}
There's no need to introduce pointers or std::list at all.

Don't use pointers in your task, list use a self allocator:) if you need poiner use unique ore shared ptr
if you need int prt with random value use
int* p = new int{rand()};
Use mt to generate a random value (http://www.cplusplus.com/reference/random/mt19937/) ande see coments in code block
#include <iostream>
#include <list>
#include <random>
#include <functional>
namespace test {
std::list<int*> __attribute__((noinline))
foo() noexcept{
// Mersenne Twister generator with random device seed
// good way and not use time spec
std::mt19937_64 generator(std::random_device{}());
// for int gen
// this a seporator for generated value
std::uniform_int_distribution<> uid(0, 256);
// make functional object to use
auto rand_gen{std::bind(uid, generator)};
std::list<int*> lst;
int i{0};
for (auto i{0}; i < 5; ++i) {
// emplase is right way now
try {
lst.emplace_back(new int{rand_gen()});
} catch (std::bad_alloc& ba) {
std::cerr << "bad_alloc caught: " << ba.what() << std::endl;
}
}
return std::move(lst);
}
}
int main() {
std::list<int*> lst{test::foo()};
for(const auto& val : lst) {
std::cout << *val << std::endl;
delete val;
}
return 0;
}
ore use /dev/urandom if you linux like user :)

A note: You would not do this in real life. You would use a container of int, possibly std::list but more likely std::vector, not pointers to int. This is probably an assignment to make the learner struggle for a while with pointers.
So let's deal in pointers and do this the hard way.
int* random = (int*)std::rand();
means Get me a random number and store the random number as a memory address. What does this address point to? Anybody's guess. It's random. That makes it a bad idea.
A pointer must point to a valid object of the same type (or has an is-a relationship with the pointer's type) or it should be pointed at a "safe" parking location like nullptr until it can be pointed at a valid object. There are exceptions to this, but you'll learn those later.
Given
I'm implementing an assignment question that requires to store a list of pointers to random integers.
std::list<int*> randomInt;
Is probably correct. But... You still need an int to point at, so
Get a valid integer,
store the random number as an integer in that integer, and
store a pointer to that integer in the list.
So how do you get a valid integer? Obviously you need more than one so,
int number; // easy, but not enough numbers.
is out. All of randomInt would point at the same place and only the last value generated would be stored.
If you don't know how many numbers you're getting you need dynamic storage and should use new
int * random = new int; // get an int from dynamic memory
*random = std::rand(); // generate random number and assign to int pointed at by random
(or a smart pointer if they are available to you). Remember everything you new you will have to delete
for (int * p:randomInt) // for all pointers in randomInt
{
delete p; // free the memory (and other stuff you'll cover later)
}
after you are finished using it to avoid memory leaks. This is disturbingly error-prone, it is sickeningly easy to have a path that misses the delete or deletes while the allocation is still needed, so avoid this in real life. Use Automatic allocation, containers and smart pointers. If you can't, embrace the power of RAII.
Where possible avoid having to mess around with managing dynamic memory, smart pointer managed or otherwise, because dynamic memory always has a cost.
In this case it looks like a maximum of five, so you can make an array
int numbers[5];
(but NOT a local variable
std::list<int*> generateInt(){
int numbers[5]; // do not use!!! FATAL!!!
as it would go out of scope and vanish at the end of the function, leaving the program with a list full of pointers to invalid objects) and point at the elements of the array. For a simple program, you could get away with a static local variable
std::list<int*> generateInt(){
static int numbers[5];
or a global variable
int numbers[5];
std::list<int*> generateInt(){
but what if the function is called more than once? The second call would destroy the results of the first call. This may be tolerable, but the responsibility for making this call and guaranteeing the program works as expected falls on the programmer.
My suspicion is the Asker is intended to use new. Check with whomever assigned the problem to see what other options they will accept.

Related

Why does my array say write access violation partially through?

Updated to be copy/pasted and run. My bad.
I know I'm probably going to get the whole "this question was asked already" but I spent sometime looking and couldn't find a matching problem. It's very possible I just don't know enough to look in the right place.
When I call InitSortedArray() it runs through a seemingly random number of elements before throwing exception: write access violation. Everytime I run it it stops at a different element number. Any ideas?
#include <array>
#include <iostream>
using namespace std;
int * toSort;
const int SIZE = 100000;
void InitSortedArray()
{
srand(0);
toSort[0] = rand() % 5;
cout << toSort[0];
for (int i = 1; i < SIZE - 1; i++)
{
srand(0);
toSort[i] = toSort[i - 1] + rand() % 5;
cout << toSort[i] << endl;
}
}
void Search()
{
toSort[SIZE];
InitSortedArray();
}
int main()
{
Search();
}
int * toSort;
allocates a pointer to some data yet to be assigned to it. No data is ever assigned. You could
int * toSort = new int[100000];
but that picks up some memory management work you don't need. Any time you use new[] sooner or later you must delete[]. Instead use
const int SIZE = 100000; // place first so we can use it below
int toSort[SIZE];
or the more modern
const int SIZE = 100000; // place first so we can use it below
std::array<int, SIZE> toSort;
to declare an array.
toSort[100000];
in Search does nothing helpful (and is in fact harmful as it invokes Undefined Behaviour by accessing outside the bounds of toSort) and should be removed.
Extra stuff:
srand reseeds and restarts the random number generator. It is only in truly rare circumstances that you want to call it more than once, and in those cases there are many better options than srand and rand.
Place a single call to srand at the top of main and make absolutely certain you want srand(0) as this will always generate the exact same numbers on a given computer. It's great for testing, but not so good if you want a different sequence every time. Typical use is srand(time(NULL)) to seed the generator based on the ever-changing flow of time. That's still not all that good, but good enough for most cases where rand is in use.
It looks like you're using an uninitialized pointer that points to random space, and trying to store elements and access elements in it. Also, your inclusion of "array" doesn't make any sense here. I believe what you want to do here is initialize your toSort array to actually point to a section of memory that you intend to point it to:
int toSort[SIZE];
instead of
int * toSort;
If you're looking to use the STL array (which is likely highly recommendable) then you need to explicitly use it:
std::array<int, SIZE> toSort;
The nice thing about using the STL is it takes care of a lot of the memory access issues you can run into like memory access violation. Another helpful thing from the STL would be vector:
#include <vector>
std::vector<int> toSort;
then later: (this adds an item to the back of the vector)
toSort.push_back(<some number>);
and to access:
int somethingElse = toSort[<index number>];
Arrays: http://en.cppreference.com/w/cpp/container/array
Vectors: http://en.cppreference.com/w/cpp/container/vector

How can I make my dynamic array or vector operate at a similar speed to a standard array? C++

I'm still quite inexperienced in C++ and i'm trying to write sum code to add numbers precisely. This is a dll plugin for some finite difference software and the code is called several million times during a run. I want to write a function where any number of arguments can be passed in and the sum will be returned. My code looks like:
#include <cstdarg>
double SumFunction(int numArgs, ...){ // this allows me to pass any number
// of arguments to my function.
va_list args;
va_start(args,numArgs); //necessary prerequisites for using cstdarg
double myarray[10];
for (int i = 0; i < numArgs; i++) {
myarray[i] = va_arg(args,double);
} // I imagine this is sloppy code; however i cannot create
// myarray{numArgs] because numArgs is not a const int.
sum(myarray); // The actual method of addition is not relevant here, but
//for more complicated methods, I need to put the summation
// terms in a list.
vector<double> vec(numArgs); // instead, place all values in a vector
for (int i = 0; i < numArgs; i++) {
vec.at(i) = va_arg(args,double);
}
sum(vec); //This would be passed by reference, of course. The function sum
// doesn't actually exist, it would all be contained within the
// current function. This is method is twice as slow as placing
//all the values in the static array.
double *vec;
vec = new double[numArgs];
for (int i = 0; i < (numArgs); i++) {
vec[i] = va_arg(args,double);
}
sum(vec); // Again half of the speed of using a standard array and
// increasing in magnitude for every extra dynamic array!
delete[] vec;
va_end(args);
}
So the problem I have is that using an oversized static array is sloppy programming, but using either a vector or a dynamic array slows the program down considerably. So I really don't know what to do. Can anyone help, please?
One way to speed the code up (at the cost of making it more complicated) is to reuse a dynamic array or vector between calls, then you will avoid incurring the overhead of memory allocation and deallocation each time you call the function.
For example declare these variables outside your function either as global variables or as member variables inside some class. I'll just make them globals for ease of explanation:
double* sumArray = NULL;
int sumArraySize = 0;
In your SumFunction, check if the array exists and if not allocate it, and resize if necessary:
double SumFunction(int numArgs, ...){ // this allows me to pass any number
// of arguments to my function.
va_list args;
va_start(args,numArgs); //necessary prerequisites for using cstdarg
// if the array has already been allocated, check if it is large enough and delete if not:
if((sumArray != NULL) && (numArgs > sumArraySize))
{
delete[] sumArray;
sumArray = NULL;
}
// allocate the array, but only if necessary:
if(sumArray == NULL)
{
sumArray = new double[numArgs];
sumArraySize = numArgs;
}
double *vec = sumArray; // set to your array, reusable between calls
for (int i = 0; i < (numArgs); i++) {
vec[i] = va_arg(args,double);
}
sum(vec, numArgs); // you will need to pass the array size
va_end(args);
// note no array deallocation
}
The catch is that you need to remember to deallocate the array at some point by calling a function similar to this (like I said, you pay for speed with extra complexity):
void freeSumArray()
{
if(sumArray != NULL)
{
delete[] sumArray;
sumArray = NULL;
sumArraySize = 0;
}
}
You can take a similar (and simpler/cleaner) approach with a vector, allocate it the first time if it doesn't already exist, or call resize() on it with numArgs if it does.
When using a std::vector the optimizer must consider that relocation is possible and this introduces an extra indirection.
In other words the code for
v[index] += value;
where v is for example a std::vector<int> is expanded to
int *p = v._begin + index;
*p += value;
i.e. from vector you need first to get the field _begin (that contains where the content starts in memory), then apply the index, and then dereference to get the value and mutate it.
If the code performing the computation on the elements of the vector in a loop calls any unknown non-inlined code, the optimizer is forced to assume that unknown code may mutate the _begin field of the vector and this will require doing the two-steps indirection for each element.
(NOTE: that the vector is passed with a cost std::vector<T>& reference is totally irrelevant: a const reference doesn't mean that the vector is const but simply puts a limitation on what operations are permitted using that reference; external code could have a non-const reference to access the vector and constness can also be legally casted away... constness of references is basically ignored by the optimizer).
One way to remove this extra lookup (if you know that the vector is not being resized during the computation) is to cache this address in a local and use that instead of the vector operator [] to access the element:
int *p = &v[0];
for (int i=0,n=v.size(); i<n; i++) {
/// use p[i] instead of v[i]
}
This will generate code that is almost as efficient as a static array because, given that the address of p is not published, nothing in the body of the loop can change it and the value p can be assumed constant (something that cannot be done for v._begin as the optimizer cannot know if someone else knows the address of _begin).
I'm saying "almost" because a static array only requires indexing, while using a dynamically allocated area requires "base + indexing" access; most CPUs however provide this kind of memory access at no extra cost. Moreover if you're processing elements in sequence the indexing addressing becomes just a sequential memory access but only if you can assume the start address constant (i.e. not in the case of std::vector<T>::operator[]).
Assuming that the "max storage ever needed" is in the order of 10-50, I'd say using a local array is perfectly fine.
Using vector<T> will use 3 * sizeof(*T) (at least) to track the contents of the vector. So if we compare that to an array of double arr[10];, then that's 7 elements more on the stack of equal size (or 8.5 in 32-bit build). But you also need a call to new, which takes a size argument. So that takes up AT LEAST one, more likely 2-3 elements of stackspace, and the implementation of new is quite possibly not straightforward, so further calls are needed, which take up further stack-space.
If you "don't know" the number of elements, and need to cope with quite large numbers of elements, then using a hybrid solution, where you have a small stack-based local array, and if numargs > small_size use vector, and then pass vec.data() to the function sum.

Copying values from one vector to another (from book)

Consider this piece of code.
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector <int *> test;
vector <int *> v;
int *a = new int;
int *b = new int;
*a = 1;
*b = 2;
v.push_back (a);
v.push_back (b);
for (int i = 0; i < 2; ++i)
{
int n = *v[i];
test.push_back (&n);
}
cout << *test[0] << " " << *test[1] << endl;
delete a;
delete b;
return 0;
}
The problem's statement is:
"Given this code, answer the following questions:
Why does "test" vector contain only 2's?
How can we change for loop to copy properly (only code inside for loop)?"
I couldn't answer any of these questions, so a little bit of help will be appreciated.
Thanks in advance.
That code introduces dangling pointers. The body of the loop looks like this:
{
int n = *v[i];
test.push_back (&n);
}
The local variable n loses scope as soon as the loop body ends, so the pointer &n is now a dangling pointer. If it happens that test contains only 2's, that's just what randomly came out of what is undefined behavior.
If you want to "properly" copy the data over to test, you can change the for loop body to this:
{
int* n = new int;
*n = *v[i];
test.push_back (n);
}
Please take the "properly" with a grain of salt...
You push two the same pointers to n into test array. n equals the last element of your first array. Note that after control flow exited the loop, all pointers to n become invalid. So, in fact your test array contains invalid pointers, not pointers to 2s.
You should create a copy of each integer:
int* n = new int(*v[i]);
test.push_back (n);
Note also that you have memory leak here. Each int created using new should be later destroyed using delete.
The first question is a trick question: The vector contains pointers to a variable that no longer exists, and dereferencing that could cause pretty much any output. I imagine on some machines and compilers it prints all 2s however.
I can't understand what the exercise is trying to do (why does it use vectors of pointers for example) so I can't really help with how to solve the problem.
One way you could do it is by making test store by value:
First change the test vector to vector <int> test;
Then change the push_back to something like test.push_back (n); and finally the print statements to remove the now-unneeded * operators.
EDIT for comment:
First, I'm suspect of this book: It shouldn't be demonstrating undefined behavior or raw pointers to single builtin types. But you can change your loop body if you want:
for (int i = 0; i < 2; ++i)
{
int* n = new int;
*n = *v[i];
test.push_back (&n);
}
Note that both this will cause a memory leak unless you later delete those pointers, a problem that storing by value eliminates.
1) I think that the premise of the question is faulty. The loop adds two elements to test, each contains the address of the automatic variable n, the scope of which is limited to the body of the loop. It's not guaranteed that n will be allocated the same memory location in both passes through the loop, but I suppose that it's likely that most compilers will reuse the same location in both passes.
Moreover, n is out of scope at the output statement. So referencing the pointers in test to those memory locations is undefined. Again, there's a good chance that they will still contain the values assigned in the loop.
So, only if the same location gets reused for n in the second pass of the loop and that location has not been overwritten at the time the output statement is executed, will the output be "2 2". There is no guarantee of either of these premises.
2) To get the output "1 2" without changing anything outside the loop, one could change the definition of n to int& n = *v[i], which would be a single character change from the given code, though the end result is rather strange.
A simpler solution would be to eliminate the temporary n and simply test.push_back(v[i]).

Assign a pointer to an array

I am trying to create an array that generates random values, then assign a pointer to that array in order to use it in other functions.
Question 1: Is this the right approach?
Question 2: When I run the code below, my pointer function generates values inconsistent with what the actual array's value is. What am I doing wrong?
int size = 100;
int theray[size];
for(int i=0; i<size; i++)
{
theray[i] = (rand()%100);
}
//Output array
cout<<"The array: ";
for(int j=0; j<size; j++)
{
cout<<theray[j]<<" ";
}
cout<<endl;
int (*parray)[100] = &theray;
cout<<"The array pointer: ";
for(int k=0; k<size; k++)
{
cout<<*parray[k]<<" ";
}
Question 1: is this the right approach?
No. The right approach is to use std::vector<int> if size is not known at compile time1, and std::array<int, size> if it is2. There is no need for pointers here.
void foo(const std::vector<int>& v)
{
// do stuff with v
}
...
std::vector<int> v(size); // vector with size elements
// do something with v
// pass v to a function
foo(v);
Question 2: when I run the code below, my pointer function generates values inconsistent with what the actual array's value is. What am I doing wrong?
If you use C++ idioms you won't even encounter this problem, so I consider the question moot. However, in your case you have a problem of operator precedence: be explicit about applying de-reference * before access []:
cout<< (*parray)[k] << " ";
1 As shown in the example, you can use an std::vector as a fixed size array, where the size need not be known at runtime. Just bear in mind that it is possible to change it's size after construction.
2In your example, size is not a compile time constant so you cannot use std::array. However, if you had declared it as const int size = 100; then it would be considered a compile time constant.
Your code is a bit off in three ways. First, there is no need to use &theray. Array names already reference a memory address. You can simply assign the pointer to theray. Second, you're declaring an array of 100 pointers. Based on your description, it sounds like you just want one pointer that points to the array. Your declaration should just be int *parray instead of int *parray [100]. Finally, once you have a pointer to the array, you can access elements of the array the same way you would with the original array, only with the name of the pointer, instead of the name of the array. Try changing your last block of code (starting with the pointer declaration to this:
int *parray;
parray = theray;
cout<<"The array pointer: ";
for(int k=0; k<size; k++)
{
cout<<parray[k]<<" ";
}
Question 1
Is this the right approach?
Usually not. It depends on what you are trying to achieve.
For high level semantics you'd in most cases use std::vector<int> or, if the size is fixed and you are using C++11, std::array<int, size>. If you actually have to go down to the pointer level, you'd usually write it like this:
int *parray = theray;
cout<<"The array pointer: ";
for(int k=0; k<size; k++)
{
cout<<parray[k]<<" ";
}
This works because arrays will degrade to pointers, and the […] subscripts work on these pointers just like they work on the original arrays.
Question 2
When I run the code below, my pointer function generates values inconsistent with what the actual array's value is, what am I doing wrong?
*parray[k] gets interpreted as *(parray[k]) while you intend to use it as (*parray)[k].
Question 1: is this the right approach?
No. Use std::vector<> for arrays whose size can change dynamically (at run-time). Prefer avoiding pointers and manual memory management.
Question 2: when I run the code below, my pointer function generates values inconsistent with what the actual array's value is. What am I doing wrong?
First of all, the fact of creating pointers so you can pass the array to a function. This is not necessary. Here is how I would use classes from the C++ Standard Library to write that program (in C++11):
#include <vector>
#include <algorithm>
#include <iostream>
#include <iterator>
// Sample function that prints the vectors's content
void foo(std::vector<int> const& v)
{
copy(begin(v), end(v), std::ostream_iterator<int>(std::cout, " "));
}
int main()
{
// Populate the vector...
size_t sz = 10;
std::vector<int> v(sz);
generate(begin(v), end(v), [] () { return rand() % 100; });
// Pass it to a function...
foo(v);
}

C++ Initializing a Global Array

Hey everyone. I am an experienced java programmer and am just learning C++.
Now I have a bit of a beginner's problem. I have an array variable x of type int.
The user will input the size of x in method B. I want to use x in method A.
void method A()
{
using int x [] blah blah blah
}
void method B()
{
int n;
cin >>n;
int x [n]; // How can I use this int x in method A without getting error: storage size x is unknown.
// Or the error 'x' was not declared in this scope.
}
EDIT: Parameter passing isn't a solution I am looking for.
DOUBLE EDIT: I do know about the vector option, but my program is cramming on time. I am creating an algorithm where every millisecond counts.
BTW I found out a way of doing it.
int x [] = {}
method B();
method A () { blah blah use x}
method B () {/*int*/ x [n]}
If you actually want an array and not a vector, and you want that array dynamically sized at runtime, you would need to create it on the heap (storing it in a pointer), and free it when you're done.
Coming from Java you need to understand that there's no garbage collection in C++ - anything you new (create on the heap) in an object you will want to clean up in the destructor with delete.
class foo
{
private:
int *array;
public:
foo() { array = NULL; };
~foo()
{
if (array != NULL)
delete [] array;
}
void createArray()
{
array = new int[5];
}
};
More info at: http://www.cplusplus.com/doc/tutorial/dynamic/
This is a version of your example that works in c++.
#include <iostream>
int *my_array;
void methodA(a,b){
my_array[a] = b;
}
int methodB(){
int n;
std::cin >> n;
my_array = new int[n];
}
int main(){
int x;
x = methodB();
methodA(x-1, 20);
delete [] my_array;
return 0;
}
Use a vector:
std::vector<int> x(n);
then pass that to method A as an argument of type std::vector<int> const &.
Edit: Or make the vector a data member of your class and set it with:
size_t n;
std::cin >> n;
x.resize(n);
In C++ you can't directly size an array with a runtime value, only with constants.
You almost certainly want vector instead:
std::vector<int> x(n);
EDIT: flesh out answer.
I can't quite tell if you are trying to learn about arrays, or if you are trying to solve some practical problem. I'll assume the latter.
The only way for method A to have access to any variable is if it is in scope. Specifically, x must either be:
a local, including a parameter (but you said no to parameter passing)
a class member, or
a global
Here is a solution in which x is a class member:
class C {
public:
std::vector<int> x;
void A() {
std::cout << x[2] << "\n"; // using x[], for example.
}
void B() {
int n;
cin >> n;
x = std::vector<int>(n); // or, as others have pointed out, x.resize(n)
}
};
Be aware that arrays in C++ are much more basic (and dangerous) than in Java.
In Java, every access to an array is checked, to make sure the element number you use is within the array.
In C++, an array is just a pointer to an allocated area of memory, and you can use any array index you like (whether within the bounds of the array, or not). If your array index is outside the bounds of the array, you will be accessing (and modifying, if you are assigning to the array element!) whatever happens to be in memory at that point. This may cause an exception (if the memory address is outside the area accessible to your process), or can cause almost anything to happen (alter another variable in your program, alter something in the operating system, format your hard disk, whatever - it is called "undefined behaviour").
When you declare a local, static or global array in C++, the compiler needs to know at that point the size of the array, so it can allocate the memory (and free it for you when it goes out of scope). So the array size must be a constant.
However, an array is just a pointer. So, if you want an array whose size you don't know at compile time, you can make one on the heap, using "new". However, you then take on the responsibility of freeing that memory (with "delete") once you have finished with it.
I would agree with the posters above to use a vector if you can, as that gives you the kind of protection from accessing stuff outside the bounds of the array that you are used to.
But if you want the fastest possible code, use an allocated array:
class C {
int [] x;
void method A(int size)
{
x = new int[size]; // Allocate the array
for(int i = 0; i < size; i++)
x[i] = i; // Initialise the elements (otherwise they contain random data)
B();
delete [] x; // Don't forget to delete it when you have finished
// Note strange syntax - deleting an array needs the []
}
void method B()
{
int n;
cin >> n;
cout << x[n];
// Be warned, if the user inputs a number < 0 or >= size,
// you will get undefined behaviour!
}
}