I've got something like this:
static int n = 0; // global static int
int *arr = new int[n]; // global int*
int randToArray(int arr[], int min, int max) {
srand(time(NULL));
for(int i = 0; i <= n; i++) {
arr[i] = (rand() % max + min);
}
}
void printArray() {
if(n) {
for(int i = 0; i < n; i++)
cout << arr[i] << endl;
} else
cout << "The array hasn't been drawed yet.";
}
And then in the main function I have a menu with a switch and options for getting random numbers and printing the array:
switch(option) {
case 1:
cout << "Set the size of the array: ";
cin >> n;
randToArray(arr, 1, 99);
break;
case 2:
printArray();
wait();
break;
}
I need my array to be available globally in order to use in several other functions.
Everything works except one thing: when I want to print the array I get working properly only 8 first elements. Then the terminal shows up some very large numbers.
That's because you use
static int n = 0;
then allocate memory for zero elements.
Change the line static int n = 256; for example, to allocate memory for 256 elements.
Or, if you read n after, allocate the memory AFTER you have read n. That is, declare the array globally first (technically a pointer), as int *arr;, then
arr = new int[n];
after cin >> n;
static is a much overloaded keyword.
The way you use it, it means translation-unit-local.
Also, you don't have any global array in your code, only a pointer initialized to point to the beginning of an allocation of 0 ints.
That allocation won't be changed if you later change n.
Related
I need some help since I'm new to c++, I have a homework question where we should read a name to a char[] and then place that input inside a dynamic array, sort the dynamic array, and then terminate the allocated memory. We have to work with a half-done written program and I don't think I'm getting the input incorrectly in the dynamic array and I have a problem with deallocating memory could someone help with some tips maybe? My contribution to the code is highlighted in ** ** thanks!
const int BUFLEN = 100; // Max length of reading buffer
void sort(char* friendList[], int n); // n is the number of elements
void print(char* friendList[], int n); // n is the number of elements
void terminate(char* friendList[], int n); // n is the number of elements
const int AMOUNT = 5;
int main()
{
char* friends[AMOUNT]; // Dynamic array with AMOUNT pcs of string pointers
char buff[BUFLEN] = { "" }; // Creates a string buffer (null terminated)
int count = 0;
while (count < AMOUNT) // enter AMOUNT number of friends
{
cout << "Name a friend: ";
cin.getline(buff, BUFLEN); // Temporary reading into string buffer
friends[count] = **new char[AMOUNT];** //. . . WRITE CODE allocating memory to the string
// WRITE CODE that adds loaded name to current location in the dynamic array
**strcpy(friends[count], buff);**
++count;
}
sort(friends, count); // Sorts the ‘count’ strings
print(friends, count); // Prints the ‘count’ first names
terminate(friends, count);// Releases all allocated memory space
return 0;
}
void sort(char* friendList[], int n)
{
// WRITE FUNCTION that sorts the strings in the friendList in alphabetical order!
**int result;
for (int i = 0; i < n - 1; i++)
{
for (int j = 0; j < n - 1 - i; j++)
{
result = strcmp(friendList[j+1], friendList[j]);
if (result < 0)
swap(friendList[j+1], friendList[j]);
}
}**
}
void print(char* friendList[], int n)
{
// WRITE FUNCTION that prints ‘n’ names from the friendList on screen!
**for (int i = 0; i < n; i++)
{
cout << friendList[i] << " " << i << endl;
}**
}
void terminate(char* friendList[], int n)
{
// WRITE FUNCTION that releases all dynamically allocated memory!
**for (int i = 0; i < n; i++)
{
delete friendList[i];
}
delete [] friendList;
cout << "deleted! ";**
}
I see a few problems with this code:
In main():
not validating that cin.getline() is successful before using the contents of buff.
AMOUNT is the wrong size to use when allocating a new char[] to store in friends[]. The correct size should be either strlen(buff)+1 or cin.gcount().
In terminate() (not to be confused with std::terminate()):
delete[]'ing the input array itself, which was not allocated with new[] to begin with and thus must not be delete[]'ed.
Instead of this statement
friends[count] = new char[AMOUNT];
you need to write
friends[count] = new char[strlen( buff ) + 1];
Pay attention to that the array friends itself is not allocated dynamically. But each its element points to a dynamically allocated array. So the function terminate can look like
void terminate(char* friendList[], int n)
{
// WRITE FUNCTION that releases all dynamically allocated memory!
for (int i = 0; i < n; i++)
{
delete [] friendList[i];
friendList[i] = nullptr;
}
cout << "deleted! ";
}
The program crashes sometimes and works perfectly fine sometimes. A variable array is declared and its size changes 2 times in the program. I am using visual studio. It is in c++.
This is the code in c++:
int sz; //size of array
std::cin >> sz; //getting size
int* arr = new int[sz]; //declaring variable array.
for (int i = 0; i < sz; i++)
{
arr[i] = i; //assigning values to all members of array
std::cout << arr[i] << std::endl; //printing the array
}
std::cin >> sz; //size changes again
for (int i = 0; i < sz; i++)
{
arr[i] = i; //assigning new values
std::cout << arr[i] << std::endl; //printing the array
}
On this line:
std::cin >> sz; //size changes again
The comment is not really correct. The variable representing the size is changed, but the array arr is not changed. So indexing into any position greater than or equal to the old size will invoke undefined behavior. This means the program may work sometimes, and not others.
To resize the arr array, after the above line you need to do:
delete [] arr;
arr = new int[sz];
If you want to resize arr you must delete the old one and allocate a new one
delete[] arr;
arr = new int [sz];
If you allocate a vector with new you should delete it after you no longer need it, and don't reuse it arbitrarily so your code would be better as:
int sz; //size of array
{
std::cin >> sz; //getting size
int* arr = new int[sz]; //declaring variable array.
for (int i = 0; i < sz; i++)
{
arr[i] = i; //assigning values to all members of array
std::cout << arr[i] << std::endl; //printing the array
}
delete [] arr; // << Delete old one here, missing in original
}
{
std::cin >> sz; //size changes again
int* arr = new int[sz];
for (int i = 0; i < sz; i++)
{
arr[i] = i; //assigning new values
std::cout << arr[i] << std::endl; //printing the array
}
delete [] arr; // <<--- Here as well, missing in original - less important, but leads to memory leak.
}
or just use std::vector<int> arr(sz); and you can ignore the delete. If you absolute need to re-use the array use arr.resize(sz);
Create a dynamic array of int with a initial space of 4. Write a function ‘append’ that appends a given value to this array. At any stage, if this function finds the array full it automatically doubles the size of array to accommodate this new value. Also write a function to display all the elements of this array. Write a main to test all these functions.
I made an attempt to solve the above question as given below. However, I am unable to get the correct code. Please help me
#include<iostream>
using namespace std;
void append(int*& array, int val, int n, int r)
{
int i,p;
int *array1;
for (i=r;i<n;i++)
array[i] = val;
if(i==n)
{
p = 2*n;
array1 = new int [p];
}
for(int j =0; j<r/2; j++)
array1[j]= array[j];
append(array1, val, p, p/2);
}
int main()
{
int q,p=0,val, n = 4;
int n1 = p/2;
int *array = new int[n];
while(1)
{
cout<<"Enter 0 to end and 1 to continue";
cin>>q;
while(q!=0)
{
cin>>val;
append(array,val,n,n1);
}
}
return 0;
}
I need to solve this without using "Classes". How shall I do it?
Your function needs to do the following:
1) Be able to check if the current append call will result in an out-of-bounds write attempt. So you need something like (and give variables explanatory names like this) this as the first line in your function:
if (array_size < item_count) {
//double size of array
}
To double the size of the array, you have to make a new array with twice the size, copy all the items over from the old array, DELETE the old array, null the old array's pointer, and somehow update the array_size variable (return to main is one option, a static int counter in the function itself is another). You may have to return a pointer to the new array to main, as well. Or maybe you can just re-address the old pointer to the new array AFTER using that pointer to delete the old array. This is all about avoiding memory leaks. So, try to come up with a method declaration like:
int append(int* arrPtr, int value, int array_size, int item_count)
This particular approach means main is getting sent back the array size as an int after each append. So you need something in main like:
array_size = append(array, val, array_size, item_count);
The tricky part will be when you make the new array:
array_size = 2 * array_size;
int* temp = new int[array_size]
//copy everything over from old array to new using arrPtr and temp
for (int i = 0; i < array_size / 2; i++) {
temp[i] = arrPtr[i]
}
//delete the contents of the old array:
delete[] arrPtr;
//pointer gymnastics to redirect arrPtr to the new array:
arrPtr = temp;
temp = nullptr;
//okay, now you are back out of the conditional and can use item_count to insert the
//value into the array (doubled or not)
arrPtr[item_count] = value;
//don't forget to return array_size, and remember main must track item_count as well.
return array_size;
That's the general gist of it. This is not a complete answer, but should give you enough to work with. Basically, most of your code has to be rewritten, and the above is not a complete solution. Good luck.
After taking cue from Double size of dynamic array I have solved it.
#include<iostream>
using namespace std;
void add_element(int* &array, int &size)
{int count = 0;
while(1)
{
int number;
cout << "What number do you want to add? " << endl;
cin >> number;
if (count == size)
{
int newSize = size * 2;
int *newArr = new int[newSize];
for (int i = 0; i < count; ++i)
{
newArr[i] = array[i];
}
delete[] array;
array = newArr;
size = newSize;
}
array[count] = number;
++count;
int k;
cout<<"Do u want to end, then press 0";
cin>>k;
if(k==0) break;
}
for(int g = 0; g<count; g++)
cout<<array[g]<<'\t';
}
int main()
{
int i,j,k,size;
cin>>size;
int* array = new int [size];
add_element(array, size);
}
For this assignment, I need to make a sorted copy of an array the user has given values to. All of my code works as intended, except for this specific part. I need this function (sortedCopy) to print out the sorted version of their array, without actually changing the array itself. As far as I can tell, to do so I need to used a constant version of the array in the function so the prototype would be something like: int *sortedCopy(const int *array, int size), but all this does is give the error shown in the title. Specifically:
main.cpp:72:29: error: assignment of read-only location '*(array +
((sizetype)(((long unsigned int)i) * 4)))' array[i] = array[min]
and it does this error twice, except with array[min] = temp; at the end instead
This is the code used, with the relevant parts of main:
#include <iostream>
using namespace std;
int* sortedCopy(const int *array, int size) {
int i, j, min, temp;
for (i = 0 ; i < size - 1; i++) {
min = i;
for (j = i + 1; j < size; j++) {
if (array[j] < array[min]) {
min = j;
}
}
temp = array[i];
array[i] = array[min];
array[min] = temp;
}
cout << "Sorted array is: " << endl;
for(int i = 0; i < size; i++) {
cout << array[i] << " ";
}
cout << endl;
// Not sure if I need to return anything or not either
}
int main() {
cout << "Please enter the size of the array." << endl;
int arraySize;
int array[arraySize];
cin >> arraySize;
cout << "Please enter integer values until the array is filled." << endl;
for (int i = 0; i != arraySize; i++) {
cout << "Value " << (i + 1) << ": ";
cin >> array[i];
cout << endl;
sortedCopy(array, arraySize);
for (int i = 0; i != arraySize; i++) { // I want this part to print the
cout << array[i] << " "; // original array entered by the user
}
}
If I remove the const part of the function, it works totally fine, except it will print the sorted array after the function is called, instead of the original array.
Firstly, C/C++ is best read "top-down":
int arraySize;
int array[arraySize]; // arraySize is undefined here!!
cin >> arraySize;
On the second line, ArraySize, might be 1, or 0, or -1000. You haven't defined it until line 3.
Also, C++ doesn't allow you to allocate arrays of variable size (unless that size is const [ so it is known at compilation time]):
int array[4];
The above is fine. This helps the operating system know how much memory to provide for you on the stack (it needs to do this before your programme starts running).
const int arraySize = 4;
int array[arraySize];
Because the C++ compiler knows that arraySize is 4, it processes this just like the above code, so this is also fine.
So to handle arrays of genuinely variable length (length that depends on inputs), you need to first read the user inputs, then use dynamic allocation ("new", or a container that does dynamic allocation for you, like a vector).
As for the problem with "const", what I think that you need to understand here is that "const" is really just a promise from the programmer: The programmer is communicating to the compiler (and any programmers reading the code) that this data is not supposed to change. All the compiler does is check whether you keep your promise (or if you send it to another function / pointer that doesn't hold that promise). So by using "const" there is no work done being done for you to actually keep the data constant - just that it will complain if you don't do the work.
int* sortedCopy(const int *array, int size) {
Above you're flagging to the compiler that the sortedCopy function will keep the data in the array constant.
array[i] = array[min];
array[min] = temp;
And here (above) you are breaking that promise.
If you don't want to edit the original array, then the easiest solution is just to copy it before you send it to your sorting function.
int main()
{
int arraySize;
int arrayMain[arraySize-1];
cout << "\n\nEnter Total Number of Elements in Array.\n\n";
cin >> arraySize;
arrayMain[arraySize-1]={0};
cout <<"\n\n" <<arrayMain;
return 0;
}
my compiler freezes when I compile the above code. I am confused on how to set a dynamic array to 0?
You use a std::vector:
std::vector<int> vec(arraySize-1);
Your code is invalid because 1) arraySize isn't initialized and 2) you can't have variable length arrays in C++. So either use a vector or allocate the memory dynamically (which is what std::vector does internally):
int* arrayMain = new int[arraySize-1] ();
Note the () at the end - it's used to value-initialize the elements, so the array will have its elements set to 0.
if you want to initialize whole array to zero do this ,
int *p = new int[n]{0};
If you must use a dynamic array you can use value initialization (though std::vector<int> would be the recommended solution):
int* arrayMain = new int[arraySize - 1]();
Check the result of input operation to ensure the variable has been assigned a correct value:
if (cin >> arraySize && arraySize > 1) // > 1 to allocate an array with at least
{ // one element (unsure why the '-1').
int* arrayMain = new int[arraySize - 1]();
// Delete 'arrayMain' when no longer required.
delete[] arrayMain;
}
Note the use of cout:
cout <<"\n\n" <<arrayMain;
will print the address of the arrayMain array, not each individual element. To print each individual you need index each element in turn:
for (int i = 0; i < arraySize - 1; i++) std::cout << arrayMain[i] << '\n';