Filling an array with random numbers using a pointer - c++

Hello Im trying to fill my array with random numbers from 1 to 50 using a pointer. When I try to do this the program crashes.
This is the declaration.
populate(arraySize, numArray);
and the code
void populate(int size, int *ptr)
{
int counter = 0;
srand(unsigned(time(0)));
while (counter < size++)
{
ptr[counter] = (rand() % 50) + 1;
counter++;
}
}
There are no errors with the code and it runs it just crashes when this method is called

srand(unsigned(time(0)));
void populate(int size, int *ptr)
{
int counter = 0;
while (counter < size)
{
ptr[counter] = (rand() % 50) + 1;
counter++;
}
}
Remove the size++ and change it to size.

Another solution would be
int randomNumber () { return (std::rand()%50 +1); }
void populate(int size, int * ptr)
{
std::srand ( unsigned ( std::time(0) ) );
std::generate (ptr,ptr+size-1, randomNumber);
}
It is assumed that prior to call this function, user much do some range validation.

I guess you are trying to iterate through the array. You wrote counter < size++, which means incrementing size (I guess it's the variable that's supposed to hold the number of items) after checking for counter < size. The ++ operator does not give you another value that equals size + 1; instead, it increments size the same way size = size + 1 does. So size will increase the same time counter increases, and the index will eventually go out of bounds, and the program will crash when trying to write to that location.
Plus, as of srand, you only need to call it once (e.g. in your main()).

Related

Program works fine with small arrays, but it is suspended when the arrays get larger. How to allocate memory to large arrays?

I'll explain my code first before going into my question in more details.
The program will continue to count the next number until the nth number is generated, and then print out that number.
Here's how it works.
With a given sequence of starting numbers, for example, 0,3,6
The 1st number is 0.
The 2nd number is 3.
The 3rd number is 6.
Now, consider the last number, 6. Since that was the first
time the number had been spoken, the 4th number spoken is 0.
(if the last number has been spoken before, then, the next number
is the difference between the turn number when it was last spoken
and the turn number of the time it was most recently spoken before
then. )
since the last number, which is the 4th number (0) has been
spoken before, the most recent place where 0 appears before the last
number is turn 1. Therefore, the 5th number is 4 - 1, which is 3.
...keep counting until the nth number.
My code works fine when n is 2022, but the program stop running when n = 30,000,000
The is how I allocate memory to my arrays
int *test_case_one = new int[30000000];
Below is my entire code
#include <iostream>
#include <string>
using namespace std;
void test_cases( int Array[]);
int isfound( int table[], int current, int range);
int main()
{
int *test_case_one = new int[30000000];
test_case_one[0] = 1;
test_case_one[1] = 3;
test_case_one[2] = 2;
test_cases(test_case_one);
delete[] test_case_one;
}
void test_cases( int Array[])
{
int *table = new int[30000000];
int turn;
int last;
table[0] = Array[0];
table[1] = Array[1];
table[2] = Array[2];
table[3] = 0;
for ( int i = 4; i < 30000000; i++)
{
last = table[i -1];
turn = isfound(table, last, i);
if ( turn != -1) {
table[i] = (i-1) - turn;
}
else {
table[i] = 0;
}
}
cout<< table[29999999] << endl;
delete[] table;
}
int isfound( int table[], int last, int range)
{
for ( int j = range-1; j > 0 ; j--) {
if ( last == table[j -1]) {
return (j - 1);
}
}
return -1;
}
How can I fix this memory overload issue?
You should not build a table of the values, but a table of last rank per value, initialized to 0. That way when you get a value, you have a direct access to next value and you algo become simply linear.
If you are sure that none of the initialization values will be greater than the expected number of iterations, then everything is fine because as other values will be index differences, this will also be less than that number.
Here is a simple code for your 0-3-6 example:
#include <iostream>
int main()
{
int number;
std::cout << "Total number (>=7): ";
std::cin >> number;
if (!std::cin || number < 5) return EXIT_FAILURE;
// 3 initial values are 0, 3, 6, so 4th will be 0
int* data = new int[number];
for (int i = 0; i < number; i++) data[i] = 0;
data[0] = 1;
data[3] = 2;
int val = 6;
for (int index = 3; index <= number; index++) {
int newval = data[val] ? index - data[val] : 0;
data[val] = index;
val = newval;
// uncomment next line to see intermediary values
//printf("%d: %d\n", index + 1, val);
}
delete[] data; // always release dynamic objects...
printf("Final %d: %d\n", number, val);
return 0;
}
BTW, in modern C++ you should rarely directly allocate a raw array with new, precisely because if you do, you will be responsible for its deletion. It is much more common and easy to use standard containers, here a std::vector. (Thanks to #EtiennedeMartel for the remark).

Comparing the sums of the elements on both sides of an element 'N' in an array(attempt 2)

I took into consideration the hints I received, I applied some modular thinking and then tried again. The program runs. Depending on the set of values I hard-wire into the elements of the array, I receive as output, the index where the sum of the elements on the left is equal to the sum of the elements on the right. I understand this to have been the objective of the exercise.
I chose not to use a vector in this exercise because I need the practice for remembering that an array has a constant pointer to position 1 and as such, when an array is passed to a function, one must remember to also pass along the size of the array, or,alternately inside the function where the array is being passed, one can loop through the array and count the number of elements therein, thereafter using count as the array size.
Please criticize my new and functional code and point out anything else that I have done wrong.
Thank you.
#include "stdafx.h"
#include <iostream>
using namespace std;
/***************************************
* RIGHT SIDE OF ARRAY
* Calculates sum of elements right of n
***************************************/
int rightSideOfArray(int arrayOne[], int size, int i)
{
int n = 0;
//loop through array and get right hand sum
for (int j = 1 + i; j < size; j++)
{
n += arrayOne[j];
}
return n;
}
/***************************************
* LEFT SIDE OF ARRAY
* Calculates sum of elements left of n
***************************************/
int leftSideOfArray(int arrayOne[], int size, int i)
{
int n2 = 0;
//find left hand sum
for (int j = i - 1; j >= 0; j--)
{
n2 += arrayOne[j];
}
return n2;
}
int main()
{
//define and declare array
int const SIZE = 7;
int arrayOne[SIZE] =
{ 1,2,3,4,3,2,1 };
int n = 0;
int n2 = 0;
int count = 0;
//do comparison
for (int i = 0; i < SIZE; i++)
{
//compare right hand and left hand side and return right values
if (rightSideOfArray(arrayOne, SIZE, i) ==
leftSideOfArray(arrayOne, SIZE, i))
counter++;
cout << i << endl;
}
if (counter == 0)
cout << -1 << endl;
system("PAUSE");
return 0;
}
Old Code: First attempt
I read a previous solution to this same query but I can't figure out where I went wrong. The challenge as I understand it is to loop through an integer array, at each, element 'i', I must add all the elements to the left of 'i' to get the 'left side sum'. Then I must add all the elements to the right of 'i' to get the 'right hand sum'. There after, I should compare the sums for the right hand and left hand sides of my array.
If both sums are equal, I should have my function return the index at which the equalization of right hand and left hand side occurred. Else, I should return -1.
Can anyone tell me why I am getting only '-1' as my answer?
int equalSidesOfAnArray(int arrayOne[], int n, int n2)
{
//loop through array and get right hand sum
for (int i = 0; i < sizeof(arrayOne); i++)
{
for (int j = 1 + i; j < sizeof(arrayOne); j++)
{
n += arrayOne[j];
n2 += arrayOne[j - 1];
}
if (n == n2)
return arrayOne[i];
else
return -1;
}
}
int main()
{
// define and declare array
int const SIZE = 7;
int arrayOne[SIZE] = { 1, 2, 3, 4, 3, 2, 1 };
int n = 0;
int n2 = 0;
int answer = equalSidesOfAnArray(arrayOne, n, n2);
cout << answer << endl;
system("PAUSE");
return 0;
}
First of all, arrayOne as parameter of the function is a pointer to the first element of the array, and sizeof(arrayOne) is the size of this pointer, not the size SIZE of your array.
And even within main(), sizeof(arrayOne) would return SIZE * sizeof(int).
As you are coding in C++, use std::vector/std::array and banish C arrays. This you save you such trouble and much more.
And think about where you are initializing n and n2 (which you don't need to pass as parameter), and returning -1.

How can i return an array c++?

I am trying to generate some lotto numbers and return the array that contain these numbers but I cant go any further; Help please
void getLotto(int rad[7]) {
int numbers[7];
for (int i = 0; i < 7; i++) {
numbers[i] = rand() % 35 + 1;
}
for (int j = 0; j < 7; j++) {
int n = rand() % 35 + 1;
if (n == numbers[j]) {
numbers[j] = rand() % 35 + 1;
return;
}
}
}
Arrays can't be returned by functions. A common thing to do is to dynamically allocate the array and return a pointer to its first element. This will work in your case but will generate a requirement for the caller to manage the memory (delete[] the new[]'ed memory). That's why C++ provides us with standard array classes: Use and return a std::vector. If you have C++11 support, return std::array.
Following may help, using Fisher–Yates_shuffle:
// Fisher–Yates_shuffle
// http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle
std::vector<int> FisherYatesShuffle(std::size_t size, std::size_t max_size, std::mt19937& gen)
{
assert(size < max_size);
std::vector<int> res(size);
for(std::size_t i = 0; i != max_size; ++i) {
std::uniform_int_distribution<> dis(0, i);
std::size_t j = dis(gen);
if (j < res.size()) {
if (i != j) {
res[i] = res[j];
}
res[j] = 1 + i;
}
}
return res;
}
Live example
std::vector and std::array are better than regular arrays, but if you want to use regular arrays you can modify your function as follows:
// Arguments: renamed the array, added N (# of array elements)
void getLotto(int numbers[], size_t N) {
//int numbers[7]; // commented out local variable
for (int i = 0; i < N; i++) {
numbers[i] = rand() % 35 + 1;
}
for (int j = 0; j < N; j++) {
int n = rand() % 35 + 1;
if (n == numbers[j]) {
numbers[j] = rand() % 35 + 1;
return;
}
}
}
The brackets in int numbers[] indicates that the argument is an array, and what is actually passed is a pointer to the first element of the array. Modifying numbers in getLotto() modifies the array passed to the function.
The second argument is of type size_t because it is the platform-dependent alias for the unsigned integral type used by your system to represent the size of objects (like arrays).
This isn't as safe in that the function has to trust that numbers actually has N elements, but this is how you have a function modify a regular array instead of a container like std::vector.
You would call the function like this:
size_t N;
int numbers[N];
getLotto(numbers, N);
C++ does not allow to return an entire array as an argument to a function. However, you can return a pointer to an array by specifying the array's name without an index.
If you want to return a single-dimension array from a function, you would have to declare a function returning a pointer as in the following example:
int * myFunction()
{
.
.
.
}
Second point to remember is that C++ does not advocate to return the address of a local variable to outside of the function so you would have to define the local variable as static variable.
Now, consider the following function, which will generate 10 random numbers and return them using an array and call this function as follows:
#include <iostream>
#include <ctime>
using namespace std;
// function to generate and retrun random numbers.
int * getRandom( )
{
static int r[10];
// set the seed
srand( (unsigned)time( NULL ) );
for (int i = 0; i < 10; ++i)
{
r[i] = rand();
cout << r[i] << endl;
}
return r;
}
// main function to call above defined function.
int main ()
{
// a pointer to an int.
int *p;
p = getRandom();
for ( int i = 0; i < 10; i++ )
{
cout << "*(p + " << i << ") : ";
cout << *(p + i) << endl;
}
return 0;
}
When the above code is compiled together and executed, it produces result something as follows
624723190
1468735695
807113585
976495677
613357504
1377296355
1530315259
1778906708
1820354158
667126415
*(p + 0) : 624723190
*(p + 1) : 1468735695
*(p + 2) : 807113585
*(p + 3) : 976495677
*(p + 4) : 613357504
*(p + 5) : 1377296355
*(p + 6) : 1530315259
*(p + 7) : 1778906708
*(p + 8) : 1820354158
*(p + 9) : 667126415
There are two main ways of accomplishing this.
note: I'm not sure what your second for loop is doing. I guess the intention was to ensure that the numbers are all unique? You might want to take a look at it as that is not what it is doing.
For the purposes of this question, I've cut it down to just generating the random numbers to populate the array.
The first is to take your code and fix it to put the generated numbers into the array that was passed in:
#include <iostream>
void getLotto(int numbers[7]) {
for (int i = 0; i < 7; i++)
{numbers[i] = rand() % 35 + 1;}
return;
}
int main()
{
srand(time(0));
int lotto_numbers[7];
getLotto(lotto_numbers);
for (int i = 0; i < 7; i++)
{std::cout<<lotto_numbers[i]<<std::endl;}
}
numbers isn't actually passed in as an int[] but instead as an int* pointing to the array. This means that any changes you make to it in the function are changed in the original data.
Bear in mind that you need to keep track of your array bounds though, as the array could be defined as
int lotto_numbers[6]
which means that
numbers[7]
would be out of bounds.
The second method is to create the array on the heap. This means that you don't need to pass in an array but you can instantiate it in the function
I'm not actually going to provide the code for this here. Mainly because for something simple like this, the memory management is more trouble than it is worth. (you need to remember to call delete[] for everything created on the heap etc).
Instead, lets use something with memory management built in:
#include <iostream>
#include <vector>
std::vector<int> getLotto() {
std::vector<int> numbers;
numbers.reserve(7);
for (int i = 0; i < 7; i++) {
//numbers[i] = rand() % 35 + 1;
//would work, but is unsafe as you could potentially reference somthing out of range
//this is safer:
numbers.push_back(rand() % 35 + 1);
}
return numbers;
}
int main()
{
srand(time(0));
std::vector<int> lotto_numbers = getLotto();
for (auto i = lotto_numbers.begin(); i != lotto_numbers.end(); i++)
{
std::cout<<*i<<std::endl;
}
}
The vector handles the memory management for you. The vector can be returned, and the returned vector will still point at the allocated memory on the heap we have just populated. We don't need to free it as this will be done automatically when the vector goes out of scope.

Keeping track of a list of integers in C, and sampling from the list

Let's just say that at the simplest, I have a function that generates random integers. Every number generated I want to tack onto the end of the list.
Then, at the end, I want to sample a random numbers from this list.
I'm quite newb at C, manoeuvring around singly-linked lists and pointer arguments, so any advice would be welcome.
edit: I have no problem switching to C++ if there are structures that would help me out. I just need lists and sampling.
Here's a go at it:
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <time.h>
int main() {
srand(time(NULL));
int size = 0;
int capacity = 4;
int *data = malloc(capacity * sizeof(int));
for (int i=0; i < 1000; ++i) {
// Allocate more space
if (size == capacity) {
capacity *= 2;
data = realloc(data, capacity * sizeof(int));
if (data == NULL)
exit(-1);
}
// Append a random number
data[size] = rand();
size++;
}
// Choose a random number (poorly)
printf("%d\n", data[rand() % size]);
}
Now, why is this code terrible?
rand() is terrible. It's allowed to return random numbers in the range [0, 32768). Or larger if your implementation supports it.
rand() is allowed to use relatively terrible algorithms to generate random numbers.
rand() % size is not necessarily uniform.
time(NULL) is a terrible seed. time(NULL) returns the current time with a precision of seconds. So if I run this code twice quickly, it will often return the same result.
So if you know how many elements you will be putting into your list
then you can just do this
double array[100] // or whateversize you want
for(int i = 0; i < 100; i++){
array[i] = yourRandomNumber;
}
double index = Rand(0,100);
return array[index];
Keep in mind I did not do the correct sytax for 'yourRandomNumber' and the Rand function. This is just an outline of what you can do.
Your second option is to create a mutable list if you do not know the size of the list before hand. I.e basically a C++ vector. This has to be coded by hand.
typedef struct
{
size_t elementsAllocated;
size_t elementsUsed;
int* buffer;
} vector;
vector* push_front(vector* v, int item)
{
if (elementsUsed == elementsAllocated)
{
// Time to grow the buffer.
int elementsAllocated = v->elementsAllocated * 2;
if (elementsAllocated <= v->elementsAllocated)
{
abort(); // Overflow occurred.
}
int* buffer = realloc(v->buffer, elementsAllocated * sizeof *buffer);
if (buffer == NULL)
{
abort();
}
// Shift the existing data over.
memmove(buffer + elementsAllocated - v->elementsUsed,
buffer + v->elementsAllocated - v->elementsUsed,
v->elementsUsed * sizeof *buffer);
v->buffer = buffer;
v->elementsAllocated = elementsAllocated;
}
// Prepend the new item.
int* p = v->buffer + v->elementsAllocated - v->elementsUsed - 1;
*p = item;
v->elementsUsed++;
return p;
}
Using std::vectors in c++
#include <iostream>
#include <vector>
int main(){
std::vector<double> myVec;
while(cin){ // this lines syntax is not correct because I don't know how you are
// getting your values
myVec.push_back(value);
}
std::cout << myVec[Rand(0, myVec.size())] << std::endl;
}
All the syntax is not correct I.e cin and rand because I don't know how you are gettting your inputs and Rand can be implemented differently. BUT the rest should be straight forward.
If you know in advance at least an upper bound on the count of points you may accept, then you can use a variation on #Jay's answer. Otherwise, you need some kind of dynamic allocation. You could use a linked list and allocate nodes as you go, but it might be faster and easier to simply malloc() an array and realloc() if you find you need more space:
#include <stdlib.h>
double select_one() {
int capacity = 100;
int count;
double rval;
double *accepted = malloc(capacity * sizeof(double));
// accepted == NULL on malloc() failure
count = 0;
while (/* more points to test */) {
double point = /* next point to test */;
if (/* point is accepted */) {
if (count >= capacity) {
/* expand the array */
double *temp;
capacity = 3 * capacity / 2;
temp = realloc(accepted, capacity * sizeof(double));
if (temp == NULL) {
/* need to handle allocation failure to avoid a memory leak */
} else {
accepted = temp;
}
}
accepted[count++] = point;
}
}
/* Note: not perfectly uniform because of the modulus */
rval = accepted[rand() % count];
/* clean up the allocated memory, AFTER selecting the value */
free(accepted);
return rval;
}

Swap elements in array to reverse an array

I got an assignment to reverse an dynamic array in C++. So far, from my logic, I thinking of loop thru the array to reverse it. And here comes my code :
int main ()
{
const int size = 10;
int num_array[size];
srand (time(NULL));
for (int count = 0; count< sizeof(num_array)/sizeof(num_array[0]) ; count++){
/* generate secret number between 1 and 100: */
num_array[count] = rand() % 100 + 1;
cout << num_array[count] << " " ;
}
reverse(num_array[size],size);
cout << endl;
system("PAUSE");
return 0;
}
void reverse(int num_array[], int size)
{
for (int count =0; count< sizeof(num_array)/sizeof(num_array[0]); count++){
cout << num_array[sizeof(num_array)/sizeof(num_array[0])-1-count] << " " ;
}
return;
}
Somehow I think my logic was there but this code doesn't works, there's some error. However, my teacher told me that this isn't the way what the question wants. And here is the question :
Write a function reverse that reverses the sequence of elements in an array. For example, if reverse is called with an array containing 1 4 9 16 9 7 4 9 11,
then the array is changed to 11 9 4 7 9 16 9 4 1.
So far, she told us in the reverse method, you need to swap for the array element. So here's my question how to swap array element so that the array entered would be reversed?
Thanks in advance.
Updated portion
int main ()
{
const int size = 10;
int num_array[size];
srand (time(NULL));
for (int count = 0; count< size ; count++){
/* generate secret number between 1 and 100: */
num_array[count] = rand() % 100 + 1;
cout << num_array[count] << " " ;
}
reverse(num_array,size);
cout << endl;
system("PAUSE");
return 0;
}
void reverse(int num_array[], const int& size)
{
for (int count =0; count< size/2; count++){
int first = num_array[0];
int last = num_array[count-1];
int temp = first;
first = last;
last = temp;
}
}
You reverse function should look like this:
void reverse(int* array, const size_t size)
{
for (size_t i = 0; i < size / 2; i++)
{
// Do stuff...
}
}
And call it like:
reverse(num_array, size);
I am no C++ programmer, however I do see an easy solution to this problem. By simply using a for loop and an extra array (of the same size) you should be able to reverse the array with ease.
By using a for loop, starting at the last element of the array, and adding them in sequence to the new array, it should be fairly simple to end up with a reversed array. It would be something like this:
Declare two arrays of the same size (10 it seems)
Array1 contains your random numbers
Array2 is empty, but can consist of 10 elements
Also declare an integer, which will keep track of the progression of the for loop, but in the opposite direction. i.e not from the end but from the start.
Counter = 0
Next you will need to create a for loop to start from the end of the first array, and add the values to the start of the second array. Thus we will create a for loop to do so. The for loop will be something like this:
for(int i = lengthOfArray1; i > 0; i--){
Array2[Counter] = Array1[i]
Counter++
}
If you only wish to print it out, you would not need the counter, or the second array, you will simply use the Array1 elements and print them out with that style of for loop.
That's it. You could set Array1 = Array2 afterward if you wished to keep Array1 the original for some reason. Hope this helps a bit, changing it to C++ is your job on this one unfortunately.
You're not actually swapping the elements in the array, you're just printing them out. I assume she wants you to actually change what is stored in the array.
As a hint, go through the array swapping the first and last element, then the 2nd and 2nd last element, etc. You only need to loop for size/2 too. As you have the size variable, just use that instead of all the sizeof stuff you're doing.
I would implement the function like following
void reverse(int A[], int N)
{
for (int i=0, j=N-1; i<j; i++, j--){
int t = A[i];
A[i] = A[j];
A[j] = t;
}
}