Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
So I can not figure out why my program halts at the delete statement inside my purge loop. It's not crashing it just won't execute or give my any sort of error.
I have double checked that I am deleting an array and need the brackets, and verified that it is valid new memory. It will not work if its called by the destructor or explicitly
int main()
{
darray DA1;
DA1.Add("Hello");
DA1.Add("Good Morning");
return 0;
}
void Add(const char * string)
{
char ** temp = new char *[m_count + 1];
for (int i = 0; i < m_count; ++i)
temp[i] = m_array[i];
temp[m_count] = new char[strlen(string)];
strcpy(temp[m_count], string);
delete[] m_array;
m_array = temp;
m_count++;
}
void Purge()
{
for (int i = 0; i < m_count; ++i)
{
delete [] m_array[i];
m_array[i] = nullptr;
}
delete[] m_array;
m_array = nullptr;
m_count = 0;
}
I expect it to go through the 2d dynamic array deleting each array and then delete the final array.
These lines contain an error:
temp[m_count] = new char[strlen(string)];
strcpy(temp[m_count], string);
... in that you allocate strlen(string) bytes, but neglect to allocate the extra byte required for the NUL terminator required at the end of the string. Thus your strcpy() command writes one byte past the end of your allocated array, invoking undefined behavior. You can correct it by changing it to this:
temp[m_count] = new char[strlen(string)+1];
strcpy(temp[m_count], string);
One separate note: manually managing heap-allocations this way is very difficult to get right, even for experienced programmers, so unless you are writing this program as an exercise in order to learn how to manually-manage heap-allocation, I highly recommend using std::string (or some similar string-class) instead of C-style char-arrays. You will save yourself a lot of unnecessary pain. (In fact, I think a std::vector<std::string> would provide you with all the functionality you are trying to implement here)
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed last month.
Improve this question
If we allocate memeory by new in c++ we should deallocate them by using delete keyword. But i want to allocated memory dynamically inside a function and return it. The problem is if i deallocate the memory before i return it causes for a undefined behavior or something else :( how do i solve this problem!??? :)
int *fn()
{
int *arr = new int[4]{1 ,4 ,9 ,16};
//delete arr; arr = nullptr;
//deleting before returning is causes undefined behavior :<
return arr;
}
int main(int argc, char *argv[])
{
int *i = fn();
delete[] i;
int *j = fn();
delete[] j;
//delete[] doesn't solve the memory leak.
return 0;
}
in above case fn() causes huge memory leak! How do i manage this memory leak without using std::vector or struct s
in above case fn() causes huge memory leak!
The entire program allocates a tiny amount of memory, so it's unclear what makes you consider the leak "huge".
int *j = fn();
int *j = fn();
delete[] i;
delete[] j;
There is a potential case where the first allocation can leak: if the second allocation fails and throws an exception. In that case the delete[] won't be executed. But you don't catch the exception, so it would cause the program to terminate, so the leak is less of a problem in that case.
how do i solve this problem!???
Use std::vector.
without using std::vector
Write your own implementation of dynamic array container.
Or, you could use std::unique_ptr<int[]>.
After your edit:
delete i;
delete j;
With this change, the behaviour of the program is undefined. The immediate fix to the UB is to use delete[] instead. But that doesn't fix the leak in case of an exception. To fix that, use a container like std::vector.
After your edit:
int *i = fn();
delete[] j;
int *j = fn();
delete[] i;
Now you've flipped the order, and leak j.
If you were to fix the order, that would fix the potential memory leak of the earlier version. It's still quite brittle since it's easy to introduce memory leaks when expanding the example to be more complex. I would still recommend using a container.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
Is deleting a copied pointer the same as deleting the original pointer?
int * a = new int;
*a = 8;
int *b = a;
delete b;
In the code above, after deleting b, should i still delete a?
In the real code I have problem with, i did
std::vector<ifstream * >Infiles(5);
for (int i = 0; i < 5; ++i){
ifstream * ptr = new ifstream;
(*ptr).open(file_names[i].c_str());
Infiles[i] = ptr;
}
/* doing a bunch of reading with Infiles */
for (int i = 0; i < Infiles.size(); ++i){
delete Infiles[i]; // this part crashes
Infiles[i] = NULL;
}
But the line delete Infiles[i]; causes crashes, what is wrong with my code?
Yes, you are absolutely correct. Deleting through a pointer makes all pointers referencing the deleted object invalid. And the best way to avoid problems like this is to stop using owning pointers in C++ code.
By the way, this fact is the best reason not to set pointers to nullptr after deleting them - since it does nothing to other copies of the same pointer, it does not make the code any safer.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
i am trying to generate an array which may be independant of dimensions. i tried doing this
#include <iostream>
using namespace std;
class array3d
{
public:
array3d(size_t* d, int dims)
{
int all = 1;
size_t* dimensions;
int* array;
for (size_t i = 0; i < dims; i++) {
all = d[i];
dimensions = new size_t[dims];
array = new int[all];
std::cout << array[i] << std::endl;
}
}
};
int main()
{
size_t d[6];
d[0] = 2;
d[1] = 3;
d[2] = 4;
d[3] = 2;
d[4] = 3;
d[5] = 4;
array3d arr(d, 6);
return 0;
}
when i compile it i end up with an array of zeros alone, i am not able to find where i going wrong. can anyone help?
I cannot really understand the logic behind you code, but if you simply want to see something printed you probably meant to do this:
array = new int [all];
//write something here first!
array[i] = some_value; <--- Note that this may access past the end of the array
std::cout << array[i] << std::endl;
Or more likely you wanted this:
std::cout << d[i] << std::endl;
Note1: You should really listen to 0d0a and use std::vector unless you really need arrays
Note2: You're doing some signed to unsigned comparisons (i < dims) - you might want to take care of those too
array = new int[all]; does not initialize the allocated memory. It will just make the allocation from heap, but leave the contents of memory as it was (or, actually, accessing the allocated but uninitialized memory may be Undefined Behaviour, strictly speaking).
You see zeros only by chance, because the memory happens to contain zeros. It is zeros probably because it has not been allocated, used and released by your program yet, and OS filled it with zeros before giving it to your program.
Additionally, std::cout << array[i] << std::endl; will be buffer overflow, if i>=all. Why do you do that anyway?
And finally, your code leaks memory like crazy. Your loop loops dims times, and with each iteration you do two allocations with new, but then you lose the returned pointers.
In short, use std::vector in C++, (almost) never use plain C arrays. If you have a clear use case for a fixed length array, use std::array. Furthermore, most of the time, if you are using naked pointers in C++ application code, you are not doing it right. Use smart pointers. This applies especially, if you are learning C++ today. Learn the modern way of doing things, it will make your life so much easier, while improving quality of your code.
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.
This is a bit unclear to me... So, if I have a function:
char *test(int ran){
char *ret = new char[ran];
// process...
return ret;
}
and then call it multiple times:
for(int i = 0; i < 100000000; i++){
char *str = test(rand()%10000000+10000000);
// process...
// delete[] str; // do i have to delete it here?
}
So the question is, do I have to use delete[] for each new[] call?
You don't have to. But if you don't delete memory you reserved with 'new' you will start running out of memory eventually (memory leak).
Yes you do, otherwise you'll have a memory leak.
It's not the greatest idea to allocate in one function and free in another, though. Why not allocate in the for loop and pass the pointer to test -- this keeps the new and delete together in the code.
The answer was already given, but as you tagged the question as C++, and not as C, this is how you probably want to do it in C++ (of course, there might be other reasons not to, but there is little chance).
vector<char> (int ran){
vector<char> ret(char);
// process...
return ret;
}
And to call it:
for(int i = 0; i < 100000000; i++){
vector<char> str = test(rand()%10000000+10000000);
// process...
}
No new, thus no delete thus no memory leak.
Actually, you also probably want to use std::string instead of char* (I used vector to give a more general example).
Don't worry of data that will be copied. The compiler will optimize it out.
Edit : ok, it might not optimize it out :) however there are big chances it will. And as long there is no performance issues, go for the simplest version.