Archived

This topic is now archived and is closed to further replies.

zackriggle

pointer question

Recommended Posts

How do I tell if a pointer has memory allcated as an array, or a pointer to a single item. Also, will this work to delete any memory allocated for a pointer [char *buffer].
  
if(buffer != NULL)
{
	if(sizeof(buffer) == 1) // we use 1 because a char is 1 byte

		delete buffer;
	else 
		delete []buffer;
};
  
Also, are pointers created as NULL? ================== My (soon-to-be) Cherished Cookie of Appreciation: -- MattB - for WinSock advice --

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Hi,

buffer is not automatically set to NULL, you will have to do this yourself.

sizeof(buffer) will not return the size of the buffer you allocated with new, it will always return 4 because this is the size of a pointer variable (regardless of what it points to).

If buffer is allocated as an array then use delete [], otherwise use delete. If you dont know, delete will work for both, but really you should know if it''s an array or not.

Share this post


Link to post
Share on other sites
First, pointers should be initialized to NULL, like this:

void * pointer = NULL;

They should also be set to null when deleted.

delete pointer;
pointer = NULL;

sizeof(pointer) == 4, no matter what data the pointer is pointing to. The pointer variable itself is of type long, which is 32-bit (or 4 bytes), so its size will always be 4.

sizeof(*pointer) is the size of the object pointed to by the pointer. However, in the case of an array, the object pointed to by the pointer is not the array itself, but the FIRST object in the array (in your example, it''s a char, so this size would be 1 even for a 1k-char array).

As a rule of thumb, you have no way to know how many objects there are inside an array, unless you STORE that information yourself along with the array( in a struc, for instance).

Hovever, there are some objects (such as std::vector) that store objects as an array, but keep track of length, and can resize themselves when needed.

I might be wrong, but I believe []delete and delete have the same effect on a single-element array, So you can use []delete safely in all cases.

The method I would advise is to create your array using malloc and free, like this:

char * buffer = (char *)malloc(size_needed);
//Use buffer here
free((void *)buffer); //(is that cast necessary?)

void * malloc(size) returns a pointer to a chunk of data of the requested size. You may then safely cast it to any other kind of data (here, char). free() is used to "delete" memory allocated through malloc(). Using "delete" on these pointers might have weird results.

In the above example, buffer would behave as a normal array of char; You would be able to read buffer, or pass buffer as a normal LPCSTR pointer argument to any function (such as strcmp).

Hope this helped.

Share this post


Link to post
Share on other sites
No, delete will NOT work for both. The behavior of a delete operator acting on an array is undefined, and therefore dangerous and probably memory-leaky.

You should never lose track of whether something is an array or a single object.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
You cannot tell if a pointer has memory allocated. You must keep track of that yourself. The easiest way to do that is to set the pointer to NULL on creation and to check against NULL.

I would HIGHLY suggest that if you do not need the power pointers give you, you do not use them. Instead use std::vector, referances, or std::auto_ptr.

Share this post


Link to post
Share on other sites
If you''re not afraid of wasting a little memory, you could always make pointers to single items one-element arrays. Then you could always use delete []. Honestly though, you should always know such basic information about your pointers.

_____________________________

And the Phoenix shall rise from the ashes...

--Thunder_Hawk -- ¦þ
______________________________

Share this post


Link to post
Share on other sites
Thanks, all of ya. I did this mainly for one function, but figured it would come in useful sometime later. What the function would do is read from an open WinSock connection (or file, doesn''t matter) specified by the first parameter. The second paramter would be a char*& for the output of the data read. I just thought that at some point in time, a pointer that was not initialized would be sent to the function. I also figured that if you call delete[] on a wild pointer, some scary shit can happen. The array-or-just-one-element part was just something else I threw in there as a just-in-case-some-other-kid-does-something-stupid-while-using-my-program type scenario.

Thanks though. I''ll just have to take it for granted that the pointers are set to NULL before being passed into the function (or we will have a huge memory leak. Like 5K/second big. When you''re playing online for 3 hours, that leads up to [gets calculator] a 50MB memory loss).

==================
My (soon-to-be) Cherished Cookie of Appreciation:

-- MattB - for WinSock advice --

Share this post


Link to post
Share on other sites
Very good idea, but i have no clue how to do it. Any suggestions? Also, I thought of running strlen() on the pointer, since I would be dealing just with char*''s. Would this solve any problems (does a wild char* return a length of 0?)

==================
My (soon-to-be) Cherished Cookie of Appreciation:

-- MattB - for WinSock advice --

Share this post


Link to post
Share on other sites

char* ReadFromWinsock(...);


What's the problem with something like that? You can get around not knowing the length of the buffer by terminating it with a NULL character like a C-style string.

EDIT: I believe that strlen() returns the number of characters in a buffer until the first NULL character. So the length of a string in a wild pointer is undefined.

[edited by - micepick on December 23, 2002 2:21:41 PM]

Share this post


Link to post
Share on other sites
[EDIT ALL]
I need it this way because I do not know ahead of time the amount of memory needed to receive one whole message. I cannot receive just a part of one message, because that will require me to totally re-do just about everything...

[edited by - zackriggle on December 23, 2002 8:43:09 PM]

Share this post


Link to post
Share on other sites
quote:
Original post by micepick

char* ReadFromWinsock(...);


What''s the problem with something like that? You can get around not knowing the length of the buffer by terminating it with a NULL character like a C-style string.

EDIT: I believe that strlen() returns the number of characters in a buffer until the first NULL character. So the length of a string in a wild pointer is undefined.


There could be a NULL character anywhere if you send anything but strings. If you''d receive this:
11010011 00000000 10110111 01011001
strlen would return 1. But you would have received 4 bytes, no only two (one char + zero character). So you''d have a data loss (Imagine receiving 100MB and having a null character at the beginning...)

Share this post


Link to post
Share on other sites
The reason I needed the char*& function (I REMEMBER NOW) is that I need to put an entire command in one char* [i can't just put part of it... my network dll isnt set up that way]. I could go about doing in any of 3 ways:

-- 1. The way suggested [not preferable]
char * x = new char [GetSizeofNextMessage()];
x = ReadWinsock(socket);

--- 2. i can do it the way I intended: ---
char * x;
ReadWinsock(socket,&x);

--- 3. i can do it through a struct, as previously mentioned (now sounding very good) ---
struct PACKET
{
char* data;
}
// function prototype
PACKET ReadWSock(SOCKET sck);

--> NOTE: <--
I think that I am going to use the struct approach. It gives me exactly what I need. I'll just not have the packet.data pointer initialized in the constructor, leaving me to KNOW that there is no memory allocated for it. The PACKETs will most likely only be filled in by the ReadWSock() function.
--> END NOTE <--


=== Note about how ~my~ messages are read in Winsock: ===
-- There are 3 parts to a message
-- 1 - A hex value (converted to ascii) containing the length of
the length of [you'll see] the data string
-- 2 - An ?-hex long number (converted to ascii with itoa).
Length is specified by value #1
-- 3 - The actual data string, X chars long [length specified by
#2]. This [#3] can be a char string, or a struct
converted to a char*

So, if I send "Hello World! This is Zach!"
it ends up being changed to:
"21AHello World! This is Zach!"
=========================================================

[edited by - zackriggle on December 23, 2002 8:41:46 PM]

Share this post


Link to post
Share on other sites