I allocated some memory (Word * wordList) for this struct:
struct Word{
int occurrences;
std::string wrd;
};
by writing:
Word * tempList = new Word[numWords + 1];
for(int i = 0; i < numWords; i++){
tempList[i] = wordList[i];
}
delete[] wordList;
wordList = tempList;
tempList = 0;
Word currWord = {1, wrd};
wordList[numWords] = currWord;
numWords++;
numWords is the size of wordList before and after this bit of code is called and wrd is a string passed into the method. This code runs to add a word when it isn't already present in wordList.
My problem is that when delete[] is called, the program stops working. I tried using delete to see what would happen and the program worked fine as far as I could tell. What is going on and why does delete[] cause my program to freeze?
wordList is a member of class WordsOfLength:
class WordsOfLength{
private:
int numWords;
Word * wordList;
public:
WordsOfLength();
WordsOfLength(int nNumWords, Word* nWordList);
~WordsOfLength();
void addWord(std::string wrd);
std::string getWord(int frequency);
friend void WordData::writeWordData(const char* fileName);
friend void WordData::setWordData(const char* fileName);
};
with constructor:
WordsOfLength::WordsOfLength(){
numWords = 0;
wordList = NULL;
}
and destructor:
WordsOfLength::~WordsOfLength(){
delete[] wordList;
wordList = 0;
}
If you have not allocated wordList anywhere before the problematic line then you are trying to dealocate unallocated memory.
Related
//prototype
void Split(char c, vector <MyString> &outputVector) const
//partial code inside split function
// create new MyString object to push into output vector
MyString substr;
substr.mString = newString;
substr.mLength = size;
// push new item
outputVector.push_back(substr);
After I step over the outputVector.push_back() line, the mString data member is not retained.
//I have two constructors
MyString()
{
mString = NULL;
mLength = 0;
}
/*************************************************
* MyList copy constructor
* creates a deep copy of a MyString item
************************************************/
MyString(const MyString ©)
{
mString = new char[copy.mLength];
int i;
for(; i < copy.mLength; i++)
{ mString[i] = copy.mString[i]; }
mString[i] = '\0';
mLength = copy.mLength;
}
You are using an uninitialized variable which is undefined behavior
int i;
for(; i < copy.mLength; i++)
Here we have no idea what i is so anything can be going on but most likely i is larger than copy.mLength so we never enter the for loop. In order to get correct behavior set i to 0 like
int i = 0;
You have another issue with
mString[i] = '\0';
By the time we reach that line i == copy.mLength but the array only has the size of copy.mLength so we are one past the end since arrays are 0 index based. Most likely you need to change your allocation to
mString = new char[copy.mLength + 1];
to give you space for the null terminator.
http://www.cplusplus.com/reference/vector/vector/push_back/
push_back copies value to vector. Does MyString class have properly defined copy constructor, that copies mString member? I would guess this might be your problem.
I think there are 2 mistakes ,you have done
1.for(i; i < copy.mLength; i++)
{ mString[i] = copy.mString[i]; }
you have to mention ,where the loop will start .
2.mString = new char[copy.mLength + 1];
mString[i] = '\0';
i think ,you got the answer :)
Correct version of copy constructor
MyString(const MyString ©)
{
mString = new char[copy.mLength + 1];
int i = 0;
for(; i < copy.mLength; i++)
{ mString[i] = copy.mString[i]; }
mString[i] = '\0';
mLength = copy.mLength;
}
I am coding this in C++. My current issue at hand is that I have to trim the whitespace from the beginning of the character array. I am not allowed to use any string functions. My idea is to count the number of whitespaces at the beginning, allocate memory based on how much less memory I would need in a character array if I didn't have those whitespaces, do so, and then copy over the new string and deallocate the original string.
My issue is that I can't seem to deallocate that string without Visual Studio hitting a break point for me. I can get it working with the code I have below, (not deallocating the roginal strig at all) d=but wouldn't that cause a memory leak?
Thanks for your help in advance.
#include <iostream>
using namespace std;
class SmartString{
private:
char* str;
public:
SmartString ( )
{
str = NULL;
}
SmartString (char *str){
int length = 0;
int copy_index = 0;
while(str[length] != '\0')
{
length++;
}
length++;
char * copy;
copy = (char*)malloc(sizeof(char) * length);
copy = new char[length];
while(copy_index < length)
{
copy[copy_index] = str[copy_index];
cout << str[copy_index];
copy_index++;
}
this -> str = copy;
}
~ SmartString()
{
if(str != NULL)
{
delete str;
free(str);
}
}
void ShowString()
{
cout << "[" << str << "]";
}
int Size()
{
if(str == NULL)
return 0;
else
{
int i = 0;
while(str[i] != '\0')
{
i++;
}
i++;
return i;
}
}
**void Trim()
{
int counter = 0;
while (str[counter] == ' ' && counter < Size())
{
counter++;
}
int new_length = Size() - (counter + 1);
char * temp;
temp = (char*) malloc(sizeof(char) * new_length);
temp = new char[new_length];
int counter_2 = 0;
while(counter_2 < Size())
{
temp[counter_2] = str[counter_2 + counter];
counter_2++;
}
str = temp;
}**
};
int main()
{
char *str;
str = " Hello";
SmartString * s = new SmartString(str);
str = "Change";
(*s).Trim();
(*s).ShowString();
system("Pause");
}
You have not used 'delete' in your main function to deallocate your 's' pointer variable, So that the destructor method of your 'SmartString' class never called. In your second constrcutor method, you I've allocated the 'copy' variable twice where it's not need And also you have some mistake in your 'Trim' method.
In your destructor method, You should remove the free(str); statement cause the delete str; statement will deallocate the 'str'. So there is no need to deallocate twice.
malloc - Allocates the requested memory and returns a pointer to it.
new X; - Do the same thing but also calls constructor method if X is a class or struct after allocating.
new X[] - Allocates dynamic array with the requested memory and returns a pointer to it.
free - Deallocates the memory previously allocated.
delete - Do the same thing but also calls destructor method if X is a class or struct after deallocating.
delete[] - Deallocates the memory previously allocated dynamic array.
new and delete is the standard memory allocation and deallocation implement of C++ language where malloc and free is the standard memory allocation and deallocation function of C language.
Here I've rewritten your 'Trim' method:
void Trim()
{
int counter = 0;
while (str[counter] == ' ' && counter < Size())
{
counter++;
}
int new_length = Size() - (counter + 1);
char * temp;
// There is no need to allocate twice
//temp = (char*) malloc(sizeof(char) * new_length);
temp = new char[new_length+1];
int counter_2 = 0;
while(counter_2 < //Size() ( Here is your big mistake. You should not use 'Size()' here )
new_length
)
{
temp[counter_2] = str[counter_2 + counter];
counter_2++;
}
temp[counter_2] = 0;
str = temp;
}
And for deallocating, you have to use the 'delete' like this:
int main()
{
char *str;
str = " Hello";
SmartString * s = new SmartString(str);
str = "Change";
(*s).Trim();
(*s).ShowString();
// use delete to deallocate a pointer
delete s;
system("pause");
}
I see three reasonable approaches to this.
One would be to modify the existing string in-place. Find the position of the first non-space character, then copy from there to the end of the string to positions starting from the first element of the string. This can't be applied to a string literal (or you'll get undefined behavior).
The second would be to allocate a new buffer and copy the data you want to keep into that buffer. In this case, you probably do not want to try to modify the original (and, especially, you don't want to try to free its data).
The third would be to (basically) re-implement a class about like std::string, that always allocates a buffer in a specific way, so it "knows" how to manipulate that buffer safely. In this case, you could/would have a constructor to create an object from a string literal, so by the time your function was invoked, it would only (even attempt to) manipulate such objects and could never accidentally try to manipulate/modify something like a string literal.
#include<iostream>
using namespace std;
class MyString{
private:
char *str=new char[10];
public:
MyString(){*str='\0';} //default constructor
MyString(char *s){ //parameterized constructor
str=s;
}
private:
int length(char* s){
int i=0;
while(s[i]!='\0')
i++;
return i;
}
char* delchar(char* s,int count,int start){
int i,j=0;
char *temp= new char[10];
for(i=start;i<start+count;i++){
s[i]=' ';
}
for(i=0;i<length(s);i++){
if(s[i]!=' ')
temp[j++]=s[i];
}
s=temp;
return s;
}
public:
MyString operator-(MyString s){
int i=0,j=0,count=0,start=-1;/* i to iterate the first string,j to iterate the second string*/
MyString temp; /* count to count the matched characters ,start to know the starting index*/
temp.str=str;
while(temp.str[i]!='\0'){
j=0;
start++;
while(s.str[j]!='\0'){
if(temp.str[i]==s.str[j]){
count++;
i++;
j++;
if(count==length(s.str)){//checks if the count
temp.str=delchar(temp.str,count,start);
i=i-count;
start=i-1;
count=0;
}
}
else{
i++;
count=0;
break;
}
}
}
return temp;
}
~MyString(){
delete str;
}
friend ostream &operator<<(ostream &stream,MyString& s){
stream<<s.str<<endl;
return stream;
}
};
int main(){
char *p= new char[20];
char *q= new char[10];
cin>>p;
cin>>q;
MyString s1(p);
MyString s2(q);
MyString s3;
s3=s1-s2;
cout<<s3;
delete p;
delete q;
return 0;
}
The above code overloads the - operator .It tries to subtract the substring from the main string for example input1:joshmathews input2:josh output:mathews. I am trying to store the output in a new MyString object s3. When I use a destructor as shown above,outputting s3
returns null. But when I don't use a destructor I get the expected output.Can anyone help?
The primary issue is that Operater- returns a local object which is copied by a default copy constructor -- that default copy constructor points s3 to the exact same memory/buffer of the temp MyString, and when that temp is destructed, it wipes out the memory s3 is using.
That is referred to as a dangling pointer. You can read more here: http://en.wikipedia.org/wiki/Dangling_pointer#Cause_of_wild_pointers
The code below is the changes I made to get your program executing and returning a valid result, while completing without error. To be clear though, there are issues with this altered version, runtime error or no runtime error, but this will help illuminate some important points.
When you define a type that allocates memory, you've really started to do somethings that don't come free. My altered version below completely got rid of the destructor, so actually it leaks memory up until the program ends. The destructor was invalid though, so removing it allowed the program the finish. But this would be one of those things that in general you shouldn't just accept.
I added a copy constructor and a copy assignment operator:
MyString(const MyString& s) {
strcpy_s(str, 10, s.str);
}
MyString& operator=(const MyString& s) {
strcpy_s(str, 10, s.str);
return *this;
}
Notice the strcpy_s in both of these. What is doing is copy the character string from the argument instead of just trying to point at the exact same string at the exact same address as the argument. If the argument gets destructed in your version, it wipes out some memory, so we can just accept default copy constructor and such since by default they are shallow copies that point to the same guts. That's one of the burdens of allocating memory -- you need to take care of that in both your destructor's ~and~ some of your constructors. This is referred to as "The Rule of Three":
If you need to explicitly declare either the destructor, copy constructor or copy assignment operator yourself, you probably need to explicitly declare all three of them.
Here's a wikipedia link about the rule of three: http://en.wikipedia.org/wiki/Rule_of_three_(C%2B%2B_programming)
You needed a destructor, so that's the clue you need the others. The reason is as I was saying -- by default you get a copy constructor for free, but it just makes everything point to the same guts if there are points are resources, but then you can't delete one without affecting everybody else.
Also, in delchar I added this line towards the bottom:
temp[j] = '\0';
Characters strings must always end at a null, and you copied only actual letter characters into temp, so without a null character, a strcpy doesn't know where to end.
If you remember I yanked out your destructor, then those are the changes I made.
The destructor also has an issue, in that if you use new to create an array, like
char* c = new char[10];
then you need to delete it in a way that indicates in was new'd as an array, like so:
delete [] c;
The next thing you should look into is how your MyString construction happens. If you step through, you'll see that the str member get new'd -- that means it holds a valid address into a buffer you can use -- but then if the MyString(char *s) constructor is used, it literally just takes this new address of s, and makes str hold that address instead -- which means the old address pointing to the valid buffer is lost, and that buffer of new'd memory cannot be freed. So that's a leak. You could use the strcpy_s strategy from the constructors I added to copy the contexts of what is pointed to by the s in MyString(char *s) into the new'd buffer. That would make a huge positive difference in the code.
And don't bother about all the elitists out there -- many of them were born doing headstands, so they can't see to relate to newbies giving things an honest effort.
Here's the full altered code:
#include<iostream>
using namespace std;
class MyString{
private:
char *str = new char[10];
public:
MyString(){ *str = '\0'; } //default constructor
MyString(char *s){ //parameterized constructor
str = s;
}
MyString(const MyString& s) {
strcpy_s(str, 10, s.str);
}
MyString& operator=(const MyString& s) {
strcpy_s(str, 10, s.str);
return *this;
}
private:
int length(char* s){
int i = 0;
while (s[i] != '\0')
i++;
return i;
}
char* delchar(char* s, int count, int start){
int i, j = 0;
char *temp = new char[10];
for (i = start; i<start + count; i++){
s[i] = ' ';
}
for (i = 0; i<length(s); i++){
if (s[i] != ' ')
temp[j++] = s[i];
}
temp[j] = '\0';
s = temp;
return s;
}
public:
MyString operator-(MyString s){
int i = 0, j = 0, count = 0, start = -1;/* i to iterate the first string,j to iterate the second string*/
MyString temp; /* count to count the matched characters ,start to know the starting index*/
temp.str = str;
while (temp.str[i] != '\0'){
j = 0;
start++;
while (s.str[j] != '\0'){
if (temp.str[i] == s.str[j]){
count++;
i++;
j++;
if (count == length(s.str)){//checks if the count
temp.str = delchar(temp.str, count, start);
i = i - count;
start = i - 1;
count = 0;
}
}
else{
i++;
count = 0;
break;
}
}
}
return temp;
}
~MyString(){
//delete str;
}
friend ostream &operator<<(ostream &stream, MyString& s){
stream << s.str << endl;
return stream;
}
};
int main(){
char *p = new char[20];
char *q = new char[10];
cin >> p;
cin >> q;
MyString s1(p);
MyString s2(q);
MyString s3;
s3 = s1 - s2;
cout << s3;
delete p;
delete q;
return 0;
}
I have been pulling my hair out on this particular issue and would like some advice. I have the following struct:
struct MqlStr // MQL String Array
{
int len;
char *string;
};
this is being passed to a function as a pointer from an external application as such:
MT4_EXPFUNC double __stdcall CheckExecutionRequests(MqlStr* RequestInfo)
within the function i am generating a number of string values that i need to assign to varies elements of the MqlStr array. the following works fine:
RequestInfo[1].string = "1";
RequestInfo[2].string = "2";
but when i use strcpy to get my generated string value into the array, it overwrites the entire array with the value i copied. for example:
string field1 = value.substr(Demark + 1, Demark2 - Demark - 1);
strncpy(RequestInfo[1].string, field1.c_str(), field1.size());
string field2 = value.substr(Demark + 1, Demark2 - Demark - 1);
strncpy(RequestInfo[2].string, field2.c_str(), field2.size());
if field1 = 1 and field2 = 2 then the entire RequestInfo[] array would be equal to 2 (the last value copied)
can someone point me in the right direction?
RequestInfo[1] = "1";
is not doing what you think. It's either
RequestInfo[1].string = "1";
if RequestInfo is a vector of MqlStr objects containing at least 2 elements, or
RequestInfo->string = "1";
if RequestInfo is a pointer to a single MqlStr object.
Have you allocated enough space for the .string pointers in your RequestInfo elements? strncpy is not allocating the space for you, use strdup for that.
You need to manage MqlStr memory in a safe manner, this can happen by using a standard container like std::string or by writing methods to allocate and deallocate the internal memory.
Here is an example of a simple class that manages its internal memory:
#include <cstdlib>
#include <iostream>
#include <string.h>
#include <sstream>
struct MqlStr
{
public:
int len;
char *string;
MqlStr() { init (); }
~MqlStr() { dealloc(); }
void assign(std::string& str) {
dealloc();
string = new char[str.length() + 1];
strncpy(string, str.c_str(), str.length());
string[str.length()] = 0;
len = str.length();
}
void dealloc() {
if(string != 0) delete [] string; init();
}
private:
void init() { string = 0; len = 0; }
MqlStr(const MqlStr &);
void operator= (const MqlStr &);
};
double CheckExecutionRequests(MqlStr* RequestInfo)
{
static int callCount = 0;
std::ostringstream stringstream; stringstream<<"callCount: "<<callCount++;
std::string field1 = stringstream.str();
RequestInfo->assign(field1);
return 1.0;
}
int main(int argc, char** argv)
{
MqlStr s[5];
std::cout<<"First call"<<std::endl;
for(unsigned i = 0; i < sizeof(s)/sizeof(s[0]); ++i)
CheckExecutionRequests(s + i);
for(unsigned i = 0; i < sizeof(s)/sizeof(s[0]); ++i)
std::cout<<"MqlStr["<<i<<"].string = "<<s[i].string<<std::endl;
std::cout<<"Second call"<<std::endl;
for(unsigned i = 0; i < sizeof(s)/sizeof(s[0]); ++i)
CheckExecutionRequests(s + i);
for(unsigned i = 0; i < sizeof(s)/sizeof(s[0]); ++i)
std::cout<<"MqlStr["<<i<<"].string = "<<s[i].string<<std::endl;
return EXIT_SUCCESS;
}
The second execution of CheckExecutionRequests with the same MqlStr instances will not corrupt the memory.
An extension to the code can be preallocation of the string size, and only reallocating the memory in the assign method if the new str.length > this.maxLength (preallocated length different from the string size).
The copy constructor and assignment operator are currently disabled, because they can cause problems if not implemented properly while managing internal memory on the heap.
A simpler solution would be to write your struct using a standard container as follows:
struct MqlStr
{
public:
std::string string;
}
And then just assign the string you get for the fields to MqlStr string.
I am getting heap corruption error while trying to free memory with delete
Here's code
char** split(char* inputstr, char delim, int& count){
char** ostr=NULL;
int numStr = 0;
int i=0,j,index=0;
while(inputstr[i]){
if(inputstr[i++]==delim)
numStr++;
}
if(inputstr[i-1]!=delim)
numStr++;
count= numStr;
ostr = new char*[numStr];
i=0;
while(inputstr[i])
{
j=i;
while(inputstr[j] && inputstr[j] != delim)
j++;
ostr[index] = new char[j-i+1];
//istr[j] = 0;
strncpy(ostr[index], inputstr+i,j-i);
ostr[index++][j-i]=0;
i=j+1;
}
return ostr;
}
for(int i=0,countStr;i<_numComp;i++){
char** _str = split(str[1+i],':',countStr);
message.lastTransList.cmpName[i] = new char[strlen(_str[0])+1];
strcpy(message.lastTransList.cmpName[i],_str[0]);
message.lastTransList.price[i] = atof(_str[1]);
for(int i=0; i<countStr;i++)
{
delete[] _str[i]; //this is working fine
_str[i] = 0;
}
delete[] _str; //exception is thrown at this line
}
I am not able to find the problem. Please help !
It's hard to see any error, there could be something wrong with your indexing that's causing a buffer overrun in the split function that's caught only when you try to delete the char** array.
How about converting to std::string and std::vectors like carlpett recommends (it's a good recommendation).
something like this:
void split(const std::string& str_, char delimiter_, std::vector<std::string>& result_)
{
std::string token;
std::stringstream stream(str_);
while( std::getline(stream, token, delimiter_) ) result_.push_back(token);
}
Then, you just call it with your string, delimiter and an empty std::vector and end up with a populated vector of substrings. You don't have to use new/delete and worry about the memory issues.