14 Replies - 999 Views - Last Post: 10 June 2013 - 08:34 AM Rate Topic: -----

#1 SWEMike  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 13
  • Joined: 09-December 10

Can't delete pointer which isn't even pointing to NULL

Posted 10 June 2013 - 04:11 AM

MyString.h
#pragma once
#include <string>

class MyString
{
private:
	char* buffer;
public:
	MyString(const char* initialInput)
	{
		if(initialInput != NULL)
		{
			buffer = new char[strlen(initialInput) + 1];
			buffer = (char*)initialInput;
		}
		else
		{
			buffer = NULL;
		}
	}

	~MyString()
	{
		if(buffer != NULL)
			delete[] buffer;
	}

	const char* getString()
	{
		return buffer;
	}

	int getLength()
	{
		return strlen(buffer);
	}
};


Main.cpp
#include <iostream>
#include "MyString.h"

int main()
{
	MyString text("Nom nom nom!");

	std::cout << "The text stored in text reads: " << text.getString() << std::endl;
	std::cout << "The length of the text stored in text is: " << text.getLength() << std::

	return 0;
}


When I run this code and the destructor is called, I get a debugger error message:
Posted Image

I don't understand it, I tested the destructor and checked what the value in the buffer is and it says the right value, so it's obviously not NULL. Why can I not delete a pointer which isn't a nullpointer?

Is This A Good Question/Topic? 0
  • +

Replies To: Can't delete pointer which isn't even pointing to NULL

#2 sepp2k  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 2089
  • View blog
  • Posts: 3,179
  • Joined: 21-June 11

Re: Can't delete pointer which isn't even pointing to NULL

Posted 10 June 2013 - 04:28 AM

View PostSWEMike, on 10 June 2013 - 01:11 PM, said:

Why can I not delete a pointer which isn't a nullpointer?


Because it does not point to memory that has been allocated with new or because it points to memory that already has been deleted. In your case it's almost certainly the former.

buffer = new char[strlen(initialInput) + 1];
buffer = (char*)initialInput;


The first line makes buffer point to memory allocated with new. The second line makes buffer point wherever initialInput points, so it now no longer points to new-allocated memory (unless initialInput points to new-allocated memory, which it probably doesn't). This also means that the memory that you allocated on line 1 is now leaked as you no longer have a pointer to it.

Also note that if initialInput points to read-only memory (which it certainly might since it's a const pointer), writing to buffer will invoke undefined behavior as it then also points to read-only memory.
Was This Post Helpful? 2
  • +
  • -

#3 baavgai  Icon User is offline

  • Dreaming Coder
  • member icon

Reputation: 5777
  • View blog
  • Posts: 12,592
  • Joined: 16-October 07

Re: Can't delete pointer which isn't even pointing to NULL

Posted 10 June 2013 - 04:42 AM

To be clear, you don't delete pointers.

Rather, pointers point to allocated memory. When you call delete on a pointer, you're saying that the allocated memory pointed to is now available again and the object it pointed to is considered deleted.

Do NOT call delete on an unallocated pointer. It's an invalid call because, well, you have nothing to actually delete. Also, if you have a valid address in the pointer, you could actually hurt yourself. In C, you'd hurt yourself no matter what. C++ will often just crash out by way of protest.
Was This Post Helpful? 3
  • +
  • -

#4 SWEMike  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 13
  • Joined: 09-December 10

Re: Can't delete pointer which isn't even pointing to NULL

Posted 10 June 2013 - 05:39 AM

Thanks, guys. I'm using a book that uses ways that Visual Studio don't really like (such as strcpy) so, I had to modify some of the code. I've gotten this to work before, and this post was the result of trying to do it from memory. I realized after a long while that I had actually checked != NULL on the wrong pointer. I fixed it. :)

And it's kind of hard to understand and use all the terms correctly, so I sometimes say things that make sense to experienced programmers, such as "delete a pointer." I know I can't delete the actual pointer, I just didn't know a better way to put it. Hopefully I'll learn the terminology on the way.
Was This Post Helpful? 0
  • +
  • -

#5 Skydiver  Icon User is offline

  • Code herder
  • member icon

Reputation: 3467
  • View blog
  • Posts: 10,687
  • Joined: 05-May 12

Re: Can't delete pointer which isn't even pointing to NULL

Posted 10 June 2013 - 06:02 AM

In C++, you don't need to check if the pointer is not null before passing it to the delete function. It can take a null pointer.
Was This Post Helpful? 1
  • +
  • -

#6 SWEMike  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 13
  • Joined: 09-December 10

Re: Can't delete pointer which isn't even pointing to NULL

Posted 10 June 2013 - 06:51 AM

View PostSkydiver, on 10 June 2013 - 06:02 AM, said:

In C++, you don't need to check if the pointer is not null before passing it to the delete function. It can take a null pointer.


O.o What the hell. XD But I'm guessing it's bad practice not to check? Or am I wrong?
Was This Post Helpful? 0
  • +
  • -

#7 SWEMike  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 13
  • Joined: 09-December 10

Re: Can't delete pointer which isn't even pointing to NULL

Posted 10 June 2013 - 07:01 AM

VC++

MyString.h
#pragma once

#include <iostream>

class MyString
{
private:
	char* buffer;
public:
	MyString(const char* initialInput)
	{
		if(initialInput != NULL)
		{
			buffer = new char[strlen(initialInput) + 1];
			buffer = (char*)initialInput;
		}
		else
			buffer = NULL;
	}

	MyString(const MyString& copySource)
	{
		if(copySource.buffer != NULL)
		{
			buffer = new char[strlen(copySource.buffer) + 1];
			buffer = copySource.buffer;
		}
		else
			buffer = NULL;
	}

	~MyString()
	{
		if(buffer != NULL)
		{
			delete [] buffer;
		}
	}

	int getLength()
	{
		return strlen(buffer);
	}

	const char* getString()
	{
		return buffer;
	}
};


Main.cpp
#include <iostream>
#include "MyString.h"

void UseMyString(MyString input)
{
	std::cout << "String buffer in MyString is " << input.getLength();
	std::cout << " characters long." << std::endl;

	std::cout << "Buffer contains: " << input.getString() << std::endl;
}

int main()
{
	MyString SayHello("Hello from MyString Class");

	UseMyString(SayHello);
	return 0;
}


When running that code using the VC++ 2012 compiler, I get this error:

Posted Image

GCC

The header is slightly modified for GCC because it accepts strcpy without doing any settings, and because string.h is needed for strlen and strcpy in GCC:

MyString.h
#ifndef MYSTRING_H
#define MYSTRING_H

#include <iostream>
#include <string.h>

class MyString
{
private:
	char* buffer;
public:
	MyString(const char* initialInput)
	{
		if(initialInput != NULL)
		{
			buffer = new char[strlen(initialInput) + 1];
			strcpy(buffer, initialInput);
		}
		else
			buffer = NULL;
	}

	MyString(const MyString& copySource)
	{
		if(copySource.buffer != NULL)
		{
			buffer = new char[strlen(copySource.buffer) + 1];
			strcpy(buffer, copySource.buffer);
		}
		else
			buffer = NULL;
	}

	~MyString()
	{
		if(buffer != NULL)
		{
			delete [] buffer;
		}
	}

	int getLength()
	{
		return strlen(buffer);
	}

	const char* getString()
	{
		return buffer;
	}
};

#endif // MYSTRING_H



Why does the code work perfectly in GCC while it does not in VC++ 2012? Is there a better way to write the code in general, or do I have to write it specifically for VC++?
Was This Post Helpful? 0
  • +
  • -

#8 Skydiver  Icon User is offline

  • Code herder
  • member icon

Reputation: 3467
  • View blog
  • Posts: 10,687
  • Joined: 05-May 12

Re: Can't delete pointer which isn't even pointing to NULL

Posted 10 June 2013 - 07:14 AM

Actually, it's bad style to check because you are simply duplicating the work that the function was meant to do.

Old time C programmers like to check for NULL before calling free(). Yes, even the free() also takes a NULL pointer. At the time, though, the memory functions were considered slow. So it was treated as a good practice not to call a function if you didn't need to and incur the cost of the call setup and cleanup. When these C programmer transitioned to C++, they carried over the practice, and those of us who didn't know better mimicked their code. That is until somebody upturned the apple cart and pointed out the improvements in compiler and runtime technology as well as processor speed making that kind of check now a bad practice because it adds visual and cognitive clutter.

This post has been edited by Skydiver: 10 June 2013 - 07:18 AM

Was This Post Helpful? 1
  • +
  • -

#9 macosxnerd101  Icon User is offline

  • Self-Trained Economist
  • member icon




Reputation: 10385
  • View blog
  • Posts: 38,434
  • Joined: 27-December 08

Re: Can't delete pointer which isn't even pointing to NULL

Posted 10 June 2013 - 07:16 AM

Related threads merged. Please avoid duplicate posting.
Was This Post Helpful? 1
  • +
  • -

#10 Skydiver  Icon User is offline

  • Code herder
  • member icon

Reputation: 3467
  • View blog
  • Posts: 10,687
  • Joined: 05-May 12

Re: Can't delete pointer which isn't even pointing to NULL

Posted 10 June 2013 - 07:24 AM

View PostSWEMike, on 10 June 2013 - 10:01 AM, said:

Why does the code work perfectly in GCC while it does not in VC++ 2012? Is there a better way to write the code in general, or do I have to write it specifically for VC++?


For both versions, you should include string.h.

The crash in VC++ is because of the same problem at the beginning of this thread, you just made your internal buffer pointer point to the incoming string, unlike your GCC implementation where you copied the contents of the incoming string into your buffer.

Instead of using strcpy(), use strncpy(). This will make the MS compiler happier because you are using a function that knows about the size of the destination buffer.
Was This Post Helpful? 1
  • +
  • -

#11 SWEMike  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 13
  • Joined: 09-December 10

Re: Can't delete pointer which isn't even pointing to NULL

Posted 10 June 2013 - 07:34 AM

View Postmacosxnerd101, on 10 June 2013 - 07:16 AM, said:

Related threads merged. Please avoid duplicate posting.

Sorry, I wasn't sure the problems were related and thought each topic was about different problems. :)

View PostSkydiver, on 10 June 2013 - 07:24 AM, said:

View PostSWEMike, on 10 June 2013 - 10:01 AM, said:

Why does the code work perfectly in GCC while it does not in VC++ 2012? Is there a better way to write the code in general, or do I have to write it specifically for VC++?


For both versions, you should include string.h.

The crash in VC++ is because of the same problem at the beginning of this thread, you just made your internal buffer pointer point to the incoming string, unlike your GCC implementation where you copied the contents of the incoming string into your buffer.

Instead of using strcpy(), use strncpy(). This will make the MS compiler happier because you are using a function that knows about the size of the destination buffer.

Thank you! I didn't think of that. :D
Was This Post Helpful? 0
  • +
  • -

#12 SWEMike  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 13
  • Joined: 09-December 10

Re: Can't delete pointer which isn't even pointing to NULL

Posted 10 June 2013 - 07:46 AM

Well, the following code does the exact same thing...

#pragma once

#include <iostream>

class MyString
{
private:
	char* buffer;
public:
	MyString(const char* initialInput)
	{
		if(initialInput != NULL)
		{
			buffer = new char[strlen(initialInput) + 1];
			strncpy_s(buffer, strlen(buffer),  initialInput, strlen(initialInput));
		}
		else
			buffer = NULL;
	}

	MyString(const MyString& copySource)
	{
		if(copySource.buffer != NULL)
		{
			buffer = new char[strlen(copySource.buffer) + 1];
			strncpy_s(buffer, strlen(buffer),  copySource.buffer, strlen(copySource.buffer));
		}
		else
			buffer = NULL;
	}

	~MyString()
	{
		if(buffer != NULL)
		{
			delete [] buffer;
		}
	}

	int getLength()
	{
		return strlen(buffer);
	}

	const char* getString()
	{
		return buffer;
	}
};


And strcpy and strncpy are both deprecated according to VC++, that's why I would use the non-standard _s versions instead.
Was This Post Helpful? 0
  • +
  • -

#13 Skydiver  Icon User is offline

  • Code herder
  • member icon

Reputation: 3467
  • View blog
  • Posts: 10,687
  • Joined: 05-May 12

Re: Can't delete pointer which isn't even pointing to NULL

Posted 10 June 2013 - 07:59 AM

You are getting the crash because you are calling strlen(buffer) on line 15. Remember that the new operator will give you uninitialized memory. Since strlen() works by finding the null terminator, who know how big or small the value returned will be. This could lead to buffer overruns if the number is larger than what you allocated, or a truncated string if the number is smaller than the string you want to copy.
Was This Post Helpful? 2
  • +
  • -

#14 SWEMike  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 13
  • Joined: 09-December 10

Re: Can't delete pointer which isn't even pointing to NULL

Posted 10 June 2013 - 08:24 AM

Well, I'm giving up on this I suppose, it just won't work. I tried sizeof instead of strlen on line 15 and 26. It'd just say that buffer is too small...

Just checked the definition for strncpy_s on MSDN and it says that it DOES want the number of elements in the array. So I would need to take the string length from something. But I'm pretty sure I won't get it to work.

Ah, I changed it to strcpy_s and put the string length of initialInput + 1 as the numberOfElements parameter (and did the same with copySource.buffer on the copy constructor)... Got it to work! Finally XD
Was This Post Helpful? 0
  • +
  • -

#15 Skydiver  Icon User is offline

  • Code herder
  • member icon

Reputation: 3467
  • View blog
  • Posts: 10,687
  • Joined: 05-May 12

Re: Can't delete pointer which isn't even pointing to NULL

Posted 10 June 2013 - 08:34 AM

Or you could follow the instructions in the warning and use _CRT_SECURE_NO_WARNINGS while you are following your book/tutorial.
Was This Post Helpful? 1
  • +
  • -

Page 1 of 1