c++ dynamically declared array fails to work - c++

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.

Related

Dynamic array only allocating one element

I have searched all over and have not found anything on this.
I have the following simple code:
#include<iostream>
using namespace std;
int main() {
int *newArray;
int size;
cout << "enter size: ";
cin >> size;
newArray = new int[size];
cin.get();
return 0;
For some reason, regardless of the number entered, the dynamic array always has only one element allocated. I am not getting any compiler errors or run time errors (other than the array issue). I have also tried
int *newArray;
newArray = new int[100];
and
const int SIZE = 100;
int *newArray;
newArray = new int[SIZE];
I get the same result.
I am using Visual Studio Community 2015 for my IDE if that makes a difference.
If anyone has any pointers (no pun intended) please let me know. Thank you.
newArray is not an array, it's just a pointer to some place in memory. It doesn't contain a number of elements, it's just an address in memory. When you do newArray = new int[n], sizeof(int)*n bytes of memory are allocated and the address of this allocated space is saved in newArray.
Visual Studio only knows that newArray is a pointer to an int. So it just shows the one number at that address. It cannot know how much memory has been allocated there.
If you want to see more than the first int, open the memory view, type newArray as the address, set up it to show ints. You will see plain memory interpreted as integers, so you will see numbers from your array. But there will be no end of these ints. After your numbers, there will be garbage.
Another option to try (I'm not sure if it works though) is to add (int[100])newArray to the Watch window.
So memory is allocated, feel free to write and read it and don't forget to delete[] it.

Proper use of delete vs delete[ ] with respect to char * in C++

I have a piece of code:
#include<iostream>
using namespace std;
int main()
{
char * str = new char;
cin >> str;
cout << str;
delete str;
}
vs.
#include<iostream>
using namespace std;
int main()
{
char * str = new char[30];
cin >> str;
cout << str;
delete []str;
}
When I give input to either program using STDIN, which program ensures that there are no memory leaks?
This doubt arose as our professor told us that a char * is basically equivalent to an array of chars only. So if I allocate heap memory as in the first case and let str 'hold' an array of chars, if I then delete str, does it delete the array completely? I know that the second case manages to do so.
I have already been through ->
delete vs delete[] operators in C++
delete vs delete[]
And thus I know that delete[] deletes memory allocated by new[] and delete does the same for new. But what if new itself allocates contiguous memory locations??
Your both first code example is wrong.
char * str = new char;
cin >> str;
You've only allocated memory for a single character. If you read anything other than an empty string, you'll write into unallocated memory and will have undefined behaviour.
if I then delete str, does it delete the array completely?
It will only delete the one character that you allocated. The rest of the string that you wrote in unallocated memory won't be directly affected by the delete. It's not a memory leak, it's a memory corruption.
vs.
char * str = new char[];
This is not legal c++. Array size must be specified.
EDIT: After your fix, the second code is correct as long as you read a string of 29 characters or shorter. If you read a longer string, you'll get undefined behaviour again.
But what if new itself allocates contiguous memory locations?
It doesn't. new (as opposed to new[]) allocates and constructs exactly one object. And delete destroys and deallocates exactly one object.
TLDR Neither program has memory leaks but the first one has undefined behaviour due to memory corruption.
I believe that you are misunderstanding what the difference is between a memory leak and a buffer overflow.
What is a buffer overflow?
A buffer overflow occurs when we have some piece of memory that we are going to store some data in. And when we store that data, we put too much data there. For example:
int x[4];
x[0] = 7;
x[1] = 8;
x[2] = 9;
x[3] = 10;
x[4] = 11; // <-- Buffer Overflow!
Your code exhibits a potential buffer overflow because cin doesn't know how much memory you've allocated. And there's no real method to tell it that when using char * arguments. So in your first example, if you were to write any string longer than the empty string, you would cause a buffer overflow. Likewise, if you were to write more than 30 characters (including the null character) to the second example, you would also cause a buffer overflow.
What is a memory leak?
A memory leak is traditionally represented this way:
char *x = new char[30];
x[0] = 'a';
x[1] = '\0';
x = new char[10]; // <-- Memory Leak!
At this point in the code, you have no ability to call delete[] on the first allocation. You have no variable that points to that pointer. That is a memory leak.
What does delete[] do?
Let's consider that there is some bucket somewhere that can give us chunks of memory. We can grab chunks of memory from that bucket via new and new[]. When we use delete and delete[], we return those chunks of memory back to the bucket.
The agreement that we make with new and delete is that once we call delete on a piece of memory, we don't continue to use it. We don't do this, because the system may reuse that piece of memory, or it may have removed all ability to access that pointer all together.
How could this possibly work?
You have this piece of code:
char *x = new char;
cin >> x;
I'd like to tell you that it's basically the same as this piece of code:
char y;
cin >> &y;
In both cases, you've allocated space for only one char. So when we call delete on x, we're only deleteing one char. The part of the code there that will likely break is that cin will think that there is enough memory allocated for whatever string it is going to try and write to that pointer.
The fact is, there probably isn't enough space. There's only space for one char. And even the string "a", takes up 2 chars.
You can't do such things.
char *ptr = new char;
means that you have allocated sizeof(char) bytes.
If you will execute cin >> ptr, and pass there more than 1 character, you will get segfault as the memory isn`t allocated.
To allocate an array of chars you need to do it in next way:
char *ptr = new char[ size ];
It will allocate size * sizeof(char) bytes.
And then you can use cin >> ptr to fill it with data.

delete[] causing heap corruption

I'm well aware that there are countless problems like this, but I searched for hours and couldn't understand what I did wrong so I would really appreciate your help. (I'm new to programming)
I need to create a dictionary manager of sorts as part of my homework but I seem to have a problem with deleting words.
I get an error message "...triggered a breakpoint".
The usual answer people get to this problem is that this is heap corruption caused by going out of bounds but I can't see if and how I caused this.
I already made something similar with bus info management and it worked perfectly so that makes me even more confused... (Obviously, I did not make the mechanism exactly the same, but even after looking at my previous code I couldn't isolate the problem)
I added the functions I believe are of concern,
The adding function:
void Add_Word(char**& dictionary, int& dictionary_size, char word[])
{
char** temp = new char*[dictionary_size + 1]; // Create a new array of appropriate size.
int i;
for (i = 0; i < dictionary_size; i++)
{
temp[i] = dictionary[i]; // Copy head pointers addresses for all existing items.
}
temp[i] = new char[strlen(word)]; // Add the space for the new word,
temp[i][strlen(word)] = '\0'; // mark its end
strcpy_s(temp[i], strlen(word) + 1, word); // then copy it.
// I'm really not so sure about what I should put in the buffer length but
// strlen(word) + 1 seemed to work... I know... not good, but strlen(word) alone caused a problem.
if (dictionary_size > 0)
delete []dictionary; // Delete previous head pointers array if there are any and
dictionary = temp; // reset the main pointer to the address of the new one.
dictionary_size++; // Finally, increase dictionary_size.
}
The deleting function:
void Delete_Word(char**& dictionary, int& dictionary_size, char* word)
{
// !!! This is where the crash thingy happens.
delete[] Search_For_Word(dictionary, dictionary_size, word); // Delete the word from the dictionary.
// Search_For_Word returns a pointer to the word it receives, from the dictionary.
char** temp = new char*[dictionary_size - 1]; // Create a new array of appropriate size.
int i;
for (i = 0; i < dictionary_size; i++)
{
if (dictionary[i][0])
temp[i] = dictionary[i]; // Copy the head pointers of the existing
// items to the new array except for the deleted word.
}
delete[] dictionary; // Delete previous head pointers array and
dictionary = temp; // reset the main pointer to the address of the new one.
dictionary_size--; // Finally, decrease dictionary_size.
}
EDIT: Any parts that are excessively inefficient or obviously broken are likely a result of me messing with my code trying to figure this out on my own (such as the calling 3 times to strlen mentioned (thanks again for that, kfsone...), or forgetting to +1 it for the '\0' to mark the end of a string
--actually, no, if we go by obvious you won't tell me my mistakes #.#).
As for the reason I'm dealing with char instead of strings and vectors please allow me to quote myself: "...as part of my homework". I just barely started programming. That, and I want to grasp the basics before moving on to using the more comfortable higher-up tools.
Change:
temp[i] = new char[strlen(word)]
To:
temp[i] = new char[strlen(word)+1]
Your code has several problems.
First, if you want to allocate a C-style string on the heap using new[], then you must pay attention to the terminating NUL character.
So, if you want to do a deep copy from a string word, then you must calculate enough room, considering strlen(word) + 1: the +1 is for the terminating NUL character.
e.g.:
// Original code (wrong):
//
// temp[i] = new char[strlen(word)];
//
// New code:
temp[i] = new char[strlen(word) + 1]; // consider terminating NUL (+1)
Moreover, following your code with explicit new[]s and delete[]s is not easy.
In modern C++, you may want to use convenient robust container classes like std::vector and string classes like std::string, instead of raw C-style pointers and strings.
You can simply store a list of strings using a std::vector<std::string>, and vector::push_back() method to add new strings to the vector. No need to complicate code with new[], delete[], strcpy_s(), etc.
And if you want to deep-copy strings, you can just use the simple natural overload of operator= for std::string, and copy constructors; e.g. std::string temp = word; will work just fine.
This is C++, why are you not using std::string instead of char buffers?
If you must use char buffer strings and the secure forms of strcpy_s know that the buffer length must always be the size of the destination buffer, never a strlen function. In your case it is a bit understandable since you created the buffer with the strlen function. But what you should do is set the value into a variable and then use that any time you need the buffer size.
Also, and where I think your bug is, you are writing temp[i][strlen(word)] = '\0'; But the actual indexes of the buffer go from 0 to strlen(word)-1 so you're writing outside the allocated memory.
The code is now working.
It was wrong all over.
I messed up pretty much any part that I could regarding the dynamic memory while trying to fix it before.
I initially didn't care about calling 3 times to strlen becuase it's just homework and a very small program but I guess it's better to get used to do things the right way...
I also dropped the copy which I evidently don't understand very well in favour of a simple for loop.
// Add function. The rest is cut.
int word_length = strlen(word);
temp[i] = new char[word_length + 1]; // Added +1 here.
temp[i][word_length] = '\0'; /* This was correct after all.
the word_length index is the correct ending.*/
for (int j = 0; j < word_length; j++) // copy replaced by for loop.
temp[i][j] = word[j];
// cut
}
void Delete_Word(char**& dictionary, int& dictionary_size, char* word)
{
delete[] Search_For_Word(dictionary, dictionary_size, word);
// There was a -1 mistake here I made in order to try and fix the thing earlier.
// No need for more, it works perfectly now.

Why am I getting EXC_BAD_ACCESS with these c++ functions?

I am doing a homework assignment and I am running into these issues.
I am getting EXC_BAD_ACCESS when I call allocate();
void* Pool::allocate() {
if( free == NULL) {
this->expandPool();
}
void* tmp = free;
void* mem = malloc(elemSize);
memcpy(&free,free,sizeof(char*)); //exec bad access right here
memcpy(tmp,mem,sizeof(elemSize));
return tmp;
}
Here is my expandPool method:
void Pool::expandPool() {
poolSize++;
// Is this the first time?
if(poolSize <= 1)
pool = new char*[poolSize];
else {
char** tmp = new char*[poolSize];
memcpy(tmp,pool,sizeof(pool));
delete [] pool;
pool = tmp;
delete [] tmp;
}
char* tmp = NULL;
char* tmp2;
for(int i = 0; i < blockSize; i++) {
tmp2 = new char;
memcpy(tmp2,&tmp,sizeof(char*));
tmp = tmp2;
}
pool[poolSize - 1] = tmp;
free = tmp;
}
If you google EXC_BAD_ACCESS, you will find that it is because you are accessing memory outside an allocated memory block. This can be for several reasons.
So, lets start at the failing point -- the memcpy: you are writing to the free pointer (&free) the content of free (free), and are copying sizeof(char *) bytes. Assuming free is declared as char *free; then that is ok, so it must be the content of free you are writing from.
Stylistically, using memcpy like this -- to copy a single pointer value -- is confusing. You are better off with something like:
free = *(char **)free;
which is equivalent to your:
memcpy(&free,free,sizeof(char*));
The value of sizeof(char*) varies between systems -- 4 on 32-bit and 8 on 64-bit -- so the amount of space allocated must be at least that big.
Ok, so lets look at the expandPool method to see what free is set to:
tmp2 = new char;
Here, you are allocating a block of memory with sizeof(char) which is 1. This needs to be at least:
tmp2 = new char[sizeof(char *)];
NOTE: Calling your variable free will override the free function, so you will need to explicitly access that function by writing ::free.
I'd start off by drawing a diagram of what you want the memory layout of the pool to be and how it will look/change (a) when empty, (b) when allocating a chunk that is free and (c) when allocating a chunk when you need to expand the pool. Annotate the diagram with the different variables (pool, tmp, tmp2 and free). This will give you an idea of what you need to do and what the code should look like.
Having a good understanding of the data structures and algorithms (through creating the diagrams) will help you get the code right.
There are several problems in your code. One that stands out to me is this part:
pool = tmp;
delete [] tmp;
To me, this makes pool point to deleted memory. Using pool later in the code causes undefined behavior, which can not be explained by the language. Failure elsewhere in the code is just to be expected.

Creating a dynamic memory in 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];