Creating a dynamic memory in c++ - c++

I'm trying to create a dynamic memory. The size of the array is determine by the user input. I'm getting the following error,
"expression must have a constant value".
it seems like I'm doing something wrong. Please help me! How can I make this dynamic?
This is what I have so far:
int* IntPtr = NULL;
int main(){
int arraySize;
cout << "How many numbers will be on the list? ";
cin >> arraySize;
IntPtr = new int[arraySize];
Contact list[arraySize]; // <-- expression must be constant
//more code
delete [] IntPtr;

You're trying to use Variable Length Arrays. Unfortunately, C++ does not allow them. (though some compiles allow them by extension)
What you need instead is to dynamically allocate the array using new. (and manually deallocate later with delete)
You're already doing this correctly with:
IntPtr = new int[arraySize];
Now you can do the same with the list variable:
Contact *list = new Contact[arraySize];
delete [] list;
Alternatively, you can use the vector class, which is often preferred over dynamic arrays.
vector<Contact> list(arraySize);

Use an std::vector<Contact> instead, or if you want to allocate a bare array do the same as you do with IntPtr:
Contact* list = new Contact[arraySize];

Related

Trying to understand C++ pointers and data type initializations

I am trying to learn C++, I have a fair bit of experience in C# and the 2 languages are so dissimilar and I am having trouble understanding data types and pointer variants of data types and the initialization of them, please consider the code below:
wchar_t *array = new wchar_t[10]; //Declaring a pointer of wchart_t and initializing to a wchar_t array of size 10 ?
auto memAddressOfPointer = &array; //auto is resolving memAddressOfPointer to a pointer of a pointer?
cout << array << endl; //Printing the memory address of array not the object created above?
cout << *array << endl; //Getting the actual value of the object (empty wchar_t array of size 10 in bytes?
cout << &array << endl; //Printing the address of the obj?
cout << memAddressOfPointer << endl; //Printing the address of the obj ?
My question is why would I create a pointer and initialize it? Why not just create an array of wchar_t? like:
wchar_t array [10];
I refer to this stack post as well:
Unable to create an array of wchar_t
Thank you for your consideration.
If you know the size of the number of elements you need to put in the array, then just use the array i.e., wchar_t arr[10];.
If you don't know the size, you can create the array at runtime using dynamic memory allocation with the required size i.e., wchar_t *arr = new wchar_t[required_size]. Once the memory is allocated, you need to deallocate it using delete[] operator for arrays and delete for non-array pointers. However I highly recommend you don't do that and instead either
Use std::wstring in this particular case which will automatically handle this for you.
Use std::vector for everything else if you can. It's a dynamic array which will grow automatically. No manual memory management etc.
In case you have to use pointers, use a smart pointer like unique_ptr or shared_ptr. The advantage of using smart pointers is that they will automatically clean up once they go out of scope.
If you know the extent of the array when writing the program, there's absolutely nothing wrong with wchar_t array [10];. If 10 is a fixed (constexpr) number - stick with that.
What wchar_t *array = new wchar_t[10]; lets you do is to let 10 be a number that you find out in run-time. You can change 10 to x and let x be a number that the user supplies or that you calculate somehow. wchar_t array [x]; when x is not a constexpr is on the other hand not valid C++ (but is available as an exension, called VLA, in some implementations).
Note: One downside with using new is that you need to make sure you delete the same pointer. This is not always simple. Using these raw pointers is therefore not what you usually want to do. Instead, use a smart pointer, like std::unique_ptr<wchar_t[]>, and the resource will be delete[]d when the pointer goes out of scope.
The advantages of creating a pointer instead of an array are the dynamic allocation that you can take advantage of and also the properties of the pointer that might help.
Consider the following code that represent the dynamic allocation and reallocation:
int x;
cin >> x;
int *oldArr = malloc(x * sizeof(int));
for(int i = 0; i < x; i++)
arr[i] = i;
cin >> x;
arr = realloc(arr, x * sizeof(int));
Here is another example that shows one of the pointer features which also you can use along with arrays.
int arr[5] = {1, 2, 3, 4 ,5};
int *ptr = arr;
cout << *ptr;
ptr++;
cout << *ptr;
cout << *(ptr + 1);
Despite these advantages and others, I think that the example you are presenting of using pointers instead of arrays is just for academic purposes to understand how to work with pointers in order to build more complex data structures using pointers in future lessons as you are using constant size arrays.

Taking value of Array size from user

I am doing an assignment for my university course and having the following trouble in my code:
cout << "Enter number of values you want to enter" << endl;
int Arraysize;
cin >> Arraysize;
int input_Arr[Arraysize];
The compiler gives an array saying that the array size has to be a constant. I have tried dynamically giving an array size, but that gives the same error. The only way it allows a variable as array size is , when the variable is made a const.
Can you tell me what is the way to get array size from the user and then declare array of that size?
Also , if you do so by dynamic memory allocation, please explain your code at each step.
Variable sized arrays are not standard C++, thus the compiler is not happy.
You have two options:
1) Use an std::vector, which dynamically grows in size automatically. However, since this is HW, you might not be allowed to use it just yet.
2) Use dynamic allocation of memory for your array, by using new and delete, like this:
#include <iostream>
using namespace std;
int main() {
int Arraysize;
cin >> Arraysize;
int *input_Arr = new int[Arraysize];
// Here you have an array called `input_Arr`, of size `Arraysize`, ready to be used (eg filled).
// when you are done with using the array, you must free the dynamic memory
delete [] input_Arr;
return 0;
}
The two points that require your attention are:
int *input_Arr = new int[Arraysize];
What it does? It dynamically allocates memory for an array called input_Arr, that will store ints. Its size is Arraysize.
Every time memory is allocated dynamically, it must gets free'd by the program. To do that, we use this code:
delete [] input_Arr;
which deletes an array called input_Arr.
If you want to use Dynamic allocation in C++, use keywords new and delete
code for this case will be
{
int size;
cin>>size;
int *my_array = new int[size]; //dynamic allocation
...
delete [] my_array; //don't forget to use delete at the end of your code
}

c++ dynamically declared array fails to work

I am trying to read the file's data into a dynamically declared array, using double *data = new double[14141414]() declaration. Note, it is rather a large file; hence large size of an array.
The problem is I can not put all the data into an array as somewhere around index=14000000 the execution would just stop.
The code compiles just fine (no errors). I did debug and the new returns an address, not 0 or NULL. So looks like there is no problem with memory allocation (ie running out of memory). I even echo-ed the file to screen without array assignment just to see that I am able to read through the file well. All looks good.
Yet, the moment I start putting data into an array, the program would just stop closer to the end but at random locations, Sometime it would be 14000000 sometimes the index would be a little bit more and sometimes a little bit less. There were couple times when the program ran well.
Does anybody know what is going on? I suspect the the computer running out of physical memory and hence this behavior of the program. But if this is so, then why does new operator return an address? Should it return 0 or NULL if memory allocate fails?
Thanks!!
UPDATE: per #Jonathan Potter's request I am including the code here. Thanks!! Really good idea!!
void importData(){
int totalLineCount = 14141414;
double *height = new (nothrow) double[totalLineCount]();
int *weight = new (nothrow) int[totalLineCount]();
double *pulse = new (nothrow) double[totalLineCount]();
string *dateTime = new (nothrow) string[totalLineCount];
int *year = new (nothrow) int[totalLineCount]();
int *month = new (nothrow) int[totalLineCount]();
int *day = new (nothrow) int[totalLineCount]();
fstream dataFile(file.location.c_str(), ios::in);
for (int i = 0; i < totalLineCount; i++) {
dataFile >> weight[i]
>> height[i]
>> pulse[i]
>> year[i]
>> dateTime[i];
} //for
dataFile.close();
delete height;
delete weight;
delete pulse;
delete dateTime;
delete year;
delete month;
delete day;
}//function end
save yourself loads of trouble, use a vector
std::vector<double> data;
data.reserve(SIZE_OF_ARRAY); // not totally required, but will speed up filling the values
vector will give you better debug messages and you won't have to deal with memory yourself.
Your "new" memory allocation block need to correct as follows, there is no need of () at end of each line.
double *height = new (nothrow) double[totalLineCount];
int *weight = new (nothrow) int[totalLineCount];
double *pulse = new (nothrow) double[totalLineCount];
string *dateTime = new (nothrow) string[totalLineCount];
int *year = new (nothrow) int[totalLineCount];
int *month = new (nothrow) int[totalLineCount];
int *day = new (nothrow) int[totalLineCount];
And you "delete" block need to correct as follows:
delete [] height;
delete []weight[];
delete []pulse;
delete []dateTime;
delete []year;
delete []month;
delete []day;
I think improper delete operation may be reason for your failure. You allocated memory for arrays but de-allocated by using pointer syntax of delete instead using array syntax.
And another probability for the issue may be lack of physical memory, because as per code you are allocating a lot of memory, not only a double array as you mentioned earlier in question. There is an array of std::string and a few more.
To avoid all memory allocation and de-allocation hurdles better you can go for std::vector in place of array. In one of your comments you raised concern of performance benefit by comparing array and std::vector. If you are using compiler optimizations , (if in case of gcc -O2) std::vector will be at par with array unless you may make some serious mistake in your implementation.

Deallocate Char Pointer

I've been trying to deallocate this array of char pointers, but I'm not sure how to fully deallocate it.
Here's the code:
char* words[4];
words[0] = new char[8];
words[1] = new char[6];
words[2] = new char[10];
words[3] = new char[16];
and heres what i tried
for (int i=0;i<4;i++)
{
delete [] words[i];// this works
}
delete [] words;//this gives an error, not sure why it doesn't work.
Can somebody please explain why this isn't correct and how to fix it
thanks in advance.
Only delete what you new. You didn't new words, so don't delete it. Presumably this code is inside a function, in which case words has automatic storage duration and will be destroyed automatically when it goes out of scope.
Moreover, don't new anything you don't have to, to save yourself the hassle of deleting it correctly (which can be surprisingly difficult). Use std::vector when you want a dynamic array, and std::string when you want a dynamic string.
It is not correct because words is not itself dynamically allocated like the pointers it contains.
words is on stack, words[i] is on heap. As a general principle you need a delete[] for each new[]. You have 4 new and you need 4 delete.
char *words[4] // on stack, doesn't need deallocation
char **words = new char*[4]; // on heap, would need deallocation too

c++ dynamic stuct pointer to char array

I'm having trouble dynamically assigning memory to a char array inside a pointer to a struct.
This is a homework assignment that has to use this struct outline:
struct Student
{
char *namePtr;
unsigned int score;
};
this is the part im having trouble with though
/***************************
* takes value from temporary value and puts into dynamic allocated Student array
***************************/
bool updateStructPtr(Student **info, unsigned int index, char *name, unsigned int score)
{
try
{
info[index]->namePtr = new char [strlen(name)+1];
if(DEBUG) cout << "size for dynamic char: " << strlen(name)+1 << endl << endl;
//copy char array into new array
strcpy(info[index]->namePtr, name);
info[index]->score = score;
}
catch (bad_alloc & param)
{
info[index]->namePtr = NULL;
return false;
}
return true;
}
my prof said:
A glance at your code reveals that you do not seem to be dynamically allocating memory for the Student structure as specified in the first sentence of step 3-2 of the algorithm I provided you.
3-2. Dynamically allocate memory for a Student structure. Place the address of this Student structure in the array of structure pointers. You will also need to dynamically allocate just enough memory to store the name. Do not store the quote characters. Populate the fields of the Student structure with the two items from Step 3-1.
The pointers in the pointer array point to random locations in memory and you are trying to use these random addresses. That could certainly explain why the program crashes. Actually there are many ways to crash this program and all steps must be followed carefully to avoid this.
but i have no idea how to fix this or where to begin.
SO isn't really intended for help with your homework.
That being said, the instructions from your teacher are quite elaborate and correct. You'll have to use new Student and new Student[] at one point or another to actually update the Student ** info that is passed to you in order to add that new Student struct you're supposed to add.
I'm guessing Student instances are not allocated before the function is called. You would have to allocate a new instance of Student via new Student and store it into info at index.
info[index] = new Student;