How can i check if char pointer is points nothing after allocated - c

I have allocated memory for a char pointer in this code and I wanted check does it points anything:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(){
char *p = (char*) malloc(sizeof(char)*10);
if(*p == 0)
printf("The pointer points nothing !\n");
}
And I checked that if it doesn't point anything. Also I print of pointer's length and it prints "3" although it prints nothing. What is reason of this and how can I check if it points nothing ?

You need to modify the check to check against the returned pointer, not the content. Something like
if( p == NULL) {
fprintf(stderr, "The pointer points nothing !\n");
return 1;
}
should do. Quoting the standard regarding the return values:
The malloc function returns either a null pointer or a pointer to the allocated space.
The null pointer is returned in case of a failure, otherwise the pointer returned should be non-equal to a null pointer.
That said,
The initial content of the pointed memory is indeterminate, do not attempt to verify it. Quoting from the standard,
The malloc function allocates space for an object whose size is specified by size and
whose value is indeterminate.
That goes for your other question regarding "checking the length" of the pointer - it's pointless. Unless you have stored (write) some value into it - there's no point trying to measure the initial content, as it is indeterminate. You may eventually run into undefined behavior.
The cast for the returned pointer by malloc() and family is superfluous. It can be totally avoided in C.
sizeof(char) is guaranteed to be 1, in C. Thus, using sizeof(char) as a multiplier, is again not needed, per se.

Related

Returning an address of a local pointer variable to main() function

In the following example, function func() returning an address of a local pointer variable to main() function. It's working fine in GCC.
So, Is it well-defined behaviour?
#include <stdio.h>
#include <stdlib.h>
int *func(void);
int *func(void)
{
int *p;
p = malloc(sizeof *p);
*p = 10;
return p;
}
int main()
{
int *ptr = func();
printf("%d\n",*ptr);
return 0;
}
No, you do not return a pointer to (address of) a local variable. That would be doing something like
int i = 10;
return &i;
Instead you return a pointer to an object allocated on the heap.
You do have a memory leak though, since you don't free the memory anywhere. Calling free should be done by the code calling your function (unless it in turn return the pointer value, where the responsibility continues upt he call-chain).
Inside func(), p is a pointer to memory allocated by malloc() (or to potentially allocated memory, since malloc() can fail, returning a null pointer; this should be checked for). If successful, this memory allocation will persist until it is explicitly freed.
The value of p is returned to the calling function, main() in this case. p is either a pointer to a successful allocation, or is a null pointer, and the returned value (which is temporary, and not an lvalue) is then assigned to ptr. So, the allocated storage can be accessed through ptr, which is a copy of the value held by p before func() returned, though the lifetime of p itself has ended now that func() has returned.
Of course ptr should be freed when it is no longer needed to avoid memory leaks. And, there is potential undefined behavior here if malloc() fails, since then ptr is a null pointer.
This is perfectly valid.
What is not guaranteed is what will happen to the variables on the stack frame once a function returns and the stack frame shrinks.
What you are returning is an address to some malloced memory and not the address of a local variable (allocated on the stack). This is very similar to how strdup() works. Here's an implementation of strdup() taken from here.
char *
strdup(str)
const char *str;
{
size_t len;
char *copy;
len = strlen(str) + 1;
if (!(copy = malloc((u_int)len)))
return (NULL);
bcopy(str, copy, len);
return (copy);
}
One obvious downside of this (as mentioned by "Some programmer dude") is that the responsibility of freeing is passed on to the caller.
This is a valid and correct code, although bit confusing.
The func is allocating memory of size int. The allocation is done via de-referencing a pointer variable of type int.
Alter allocation the integer value of 10 is set in the memory. 10 should be set as integer (can be compiler dependent). But definitely will not be of greater than the size of integer so should be safe operation.
After that the pointer value is returned by the function.
In main() the returned pointer is set to another integer pointer. This points to the original memory allocated by malloc().
After that the de-referenced integer pointer is printed in the printf() statement. This will print the value of 10.
What is missing is the free() call, which is not the good behaviour in here.
This can be a good academic exercise for kids.

What is wrong with malloc?

Even if i allocate 0 byte the program works.Am i doing something wrong ?
#include <stdio.h>
#include <stdlib.h>
int main()
{
char *str;
printf("memory address of str %p %p\n",&str,str);
/* Initial memory allocation */
str = (char*)malloc(0);
printf("memory address of str %p %p\n",&str,str);
strcpy(str,"abc");
printf(" string = %s %p %p\n", str,&str, str);
free(str);
return(0);
}
From malloc documentation:
If size is zero, the return value depends on the particular library
implementation (it may or may not be a null pointer), but the returned
pointer shall not be dereferenced.
Open Group says:
If the size of the space requested is 0, the behavior is
implementation-defined: the value returned shall be either a null
pointer or a unique pointer.
That means when size is 0, malloc() returns either NULL or a unique pointer that can be freed afterwards.
Am I doing something wrong?
Yes, the thing you are doing wrong is:
str = (char*)malloc(0);
strcpy(str,"abc");
If you allocate 0 bytes then you are only allowed to store 0 bytes there. Not 4 ('a', 'b', 'c' and the terminating null character).
Allocating some memory means reserving that memory for you, but even if some memory isn't reserved for you, you can sometimes still write to it - like nothing stops you from putting items in someone else's trolley at the supermarket.

Difference between initializing a string with (char *)malloc(0) and NULL

Why allocating a 0 size char block works in this case? But if I write char *string = NULL; it won't work.
I'm using Visual Studio.
int main()
{
char *string = (char *)malloc(0);
string[0] = 'a';
string[1] = 'b';
string[2] = 'c';
string[3] = 'd';
string[4] = '\0';
printf("%s\n",string);
return 0;
}
First let me state, as per the man page of malloc()
The malloc() function allocates size bytes and returns a pointer to the allocated memory. The memory is not initialized. If size is 0, then malloc() returns either NULL, or a unique pointer value that can later be successfully passed to free().
a call like malloc(0) is valid itself, but then, we need to check the validity of the returned pointer. It can either
Return NULL
Return a pointer which can be passed to free().
but anyways, dereferencing that pointer is not allowed. It will cause out-of-bound memory access and cause undefined behaviour.
That said, two important things to mention,
Please see why not to cast the return value of malloc() and family in C.
Please check the return value of malloc() before using the returned pointer.
So, to answer your question,
Difference between initializing a string with (char *)malloc(0) and NULL
Do not use malloc(0) in this case, as a NULL check on the pointer may fail, giving the wrong impression of a valid allocation of the memory to the pointer. Always use NULL for initialization.
The above code invokes undefined behavior. You have allocated insufficient memory and you are accessing invalid addresses.
According to the specifications, malloc(0) will return either "a null pointer or a unique pointer that can be successfully passed to free()".
malloc definition:
Allocates a block of size bytes of memory, returning a pointer to the
beginning of the block.
The content of the newly allocated block of memory is not initialized,
remaining with indeterminate values.
If size is zero, the return value depends on the particular library
implementation (it may or may not be a null pointer), but the returned
pointer shall not be dereferenced.
Taken from here and found this related question.

Pointer pointing to an empty array

I have a pointer that is pointing to the start of an array, but I need to check that it is unallocated. I thought of dereferencing the pointer and checking if NULL but that leads to a type error. Can anyone see what I'm doing wrong?
int mydispose(int *array){
int i = 0;
if(*array == NULL){
return 1;
}
return ;
}
EDIT: Sorry if I was unclear: I have a pointer that points to the start of an array, but I wish to check whether the array is empty.
*array == NULL is wrong. You are dereferencing the pointer first (which could lead to a segfault if the pointer really is null) and then comparing its int value to a pointer value. Moreover, your compiler will perfectly accept that erroneous expression if NULL is defined as just 0 and not (void *) 0.
You should be checking array == NULL to see if the passed pointer refers to anything, and then dereference it only in case it's not NULL.
Be aware, however, that dereferencing a non-null pointer isn't guaranteed to be a safe operation either. If the pointer contains a garbage value because it was allocated on the stack and not initialized, or if it refers to a deallocated region of memory, nasty bugs can happen.
You want if (array == NULL) -- but unless you first initialize array to NULL, it won't do any good either. I think you'd be better off backing up and telling us a bit more about what you're trying to accomplish, and trying to get help trying to accomplish your overall goal.
The only safe way to determine the allocation status of *array is to:
Make sure *array is set to NULL is not allocated. int *array = NULL;
Check if the array is NULL: if (array == NULL) return -1;
You can't reliably check if some memory location is allocated. *array is not a valid code, because it's the same as array[0], but array[0] is not allocated. Non-allocated memory location can contain any value.
The only option is to ensure that you get the information whether the array is allocated alongside with your array. A popular option is representing unallocated array as NULL, but you may choose other option as well.
By the way, there is a difference between an empty array (that is, array of size 0), and array which is not allocated at all. The first option occurs when you use malloc(0), the second when your pointer is not initialized at all. For malloc(0) it's allowed to return NULL, but it's allowed to return a non-NULL pointer (which you however can't dereference) as well. Both ways are valid according to the standard.
The immediate problem with your code is that you dereferencing array before comparing it to NULL. The type of the expression *array is int, not int *. Leave off the dereference operator and the types will match:
if (array == NULL) {...}
Note that an uninitialized pointer is only guaranteed to contain NULL if it was declared with static extent (i.e. it was either declared at file scope or with the static keyword in front of it). Similarly, calling free on a pointer won't set that pointer value to NULL; it will contain the same pointer value as before, but it will now be invalid.
You must use it like this:
if(array == NULL) ...

What does malloc(0) return? [duplicate]

This question already has answers here:
What's the point of malloc(0)?
(17 answers)
Closed 8 years ago.
What does malloc(0) return?
Would the answer be same for realloc(malloc(0),0)?
#include<stdio.h>
#include<malloc.h>
int main()
{
printf("%p\n", malloc(0));
printf("%p\n", realloc(malloc(0), 0));
return 0;
}
Output from Linux GCC:
manav#manav-workstation:~$ gcc -Wall mal.c
manav#manav-workstation:~$ ./a.out
0x9363008
(nil)
manav#manav-workstation:~$
The output keep changing everytime for malloc(0). Is this a standard answer? And why would anyone be interested in getting such a pointer, other than academic research?
EDIT:
If malloc(0) returns dummy pointer, then how does following works:
int main()
{
void *ptr = malloc(0);
printf("%p\n", realloc(ptr, 1024));
return 0;
}
EDIT:
The following code outputs "possible" for every iteration. Why should it not fail ?
#include<stdio.h>
#include<malloc.h>
int main()
{
int i;
void *ptr;
printf("Testing using BRUTE FORCE\n");
for (i=0; i<65000; i++)
{
ptr = malloc(0);
if (ptr == realloc(ptr, 1024))
printf("Iteration %d: possible\n", i);
else
{
printf("Failed for iteration %d\n", i);
break;
}
}
return 0;
}
Others have answered how malloc(0) works. I will answer one of the questions that you asked that hasn't been answered yet (I think). The question is about realloc(malloc(0), 0):
What does malloc(0) return? Would the answer be same for realloc(malloc(0),0)?
The standard says this about realloc(ptr, size):
if ptr is NULL, it behaves like malloc(size),
otherwise (ptr is not NULL), it deallocates the old object pointer to by ptr and returns a pointer to a new allocated buffer. But if size is 0, C89 says that the effect is equivalent to free(ptr). Interestingly, I can't find that statement in C99 draft (n1256 or n1336). In C89, the only sensible value to return in that case would be NULL.
So, there are two cases:
malloc(0) returns NULL on an implementation. Then your realloc() call is equivalent to realloc(NULL, 0). That is equivalent to malloc(0) from above (and that is NULL in this case).
malloc(0) returns non-NULL. Then, the call is equivalent to free(malloc(0)). In this case, malloc(0) and realloc(malloc(0), 0) are not equivalent.
Note that there is an interesting case here: in the second case, when malloc(0) returns non-NULL on success, it may still return NULL to indicate failure. This will result in a call like: realloc(NULL, 0), which would be equivalent to malloc(0), which may or may not return NULL.
I am not sure if the omission in C99 is an oversight or if it means that in C99, realloc(ptr, 0) for non-NULL ptr is not equivalent to free(ptr). I just tried this with gcc -std=c99, and the above is equivalent to free(ptr).
Edit: I think I understand what your confusion is:
Let's look at a snippet from your example code:
ptr = malloc(0);
if (ptr == realloc(ptr, 1024))
The above is not the same as malloc(0) == realloc(malloc(0), 1024). In the second, the malloc() call is made twice, whereas in the first, you're passing a previously allocated pointer to realloc().
Let's analyze the first code first. Assuming malloc(0) doesn't return NULL on success, ptr has a valid value. When you do realloc(ptr, 1024), realloc() basically gives you a new buffer that has the size 1024, and the ptr becomes invalid. A conforming implementation may return the same address as the one already in ptr. So, your if condition may return true. (Note, however, looking at the value of ptr after realloc(ptr, 1024) may be undefined behavior.)
Now the question you ask: malloc(0) == realloc(malloc(0), 1024). In this case, let's assume that both the malloc(0) on the LHS and RHS returns non-NULL. Then, they are guaranteed to be different. Also, the return value from malloc() on the LHS hasn't been free()d yet, so any other malloc(), calloc(), or realloc() may not return that value. This means that if you wrote your condition as:
if (malloc(0) == realloc(malloc(0), 1024)
puts("possible");
you won't see possible on the output (unless both malloc() and realloc() fail and return NULL).
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
void *p1;
void *p2;
p1 = malloc(0);
p2 = realloc(p1, 1024);
if (p1 == p2)
puts("possible, OK");
/* Ignore the memory leaks */
if (malloc(0) == realloc(malloc(0), 1024))
puts("shouldn't happen, something is wrong");
return 0;
}
On OS X, my code didn't output anything when I ran it. On Linux, it prints possible, OK.
malloc(0) is Implementation Defined as far as C99 is concerned.
From C99 [Section 7.20.3]
The order and contiguity of storage allocated by successive calls to the calloc,
malloc, and realloc functions is unspecified. The pointer returned if the allocation
succeeds is suitably aligned so that it may be assigned to a pointer to any type of object
and then used to access such an object or an array of such objects in the space allocated
(until the space is explicitly deallocated). The lifetime of an allocated object extends
from the allocation until the deallocation. Each such allocation shall yield a pointer to an
object disjoint from any other object. The pointer returned points to the start (lowest byte
address) of the allocated space. If the space cannot be allocated, a null pointer is
returned. If the size of the space requested is zero, the behavior is implementation-
defined: either a null pointer is returned, or the behavior is as if the size were some
nonzero value, except that the returned pointer shall not be used to access an object.
In C89, malloc(0) is implementation dependent - I don't know if C99 has fixed this or not. In C++, using:
char * p = new char[0];
is well defined - you get a valid, non-null pointer. Of course, you can't use the pointer to access what it points to without invoking undefined behaviour.
As to why this exists, it is convenient for some algorithms, and means you don't need to litter your code with tests for zero values.
C99 standard
If the space cannot be allocated, a
nullpointer is returned. If the size
of the space requested is zero, the
behavior is implementation-defined:
either a null pointer is returned, or
the behavior is as if the size were
some nonzero value, except that the
returned pointer shall not be used to
access an object.
The comp.lang.c FAQ has the following to say:
The ANSI/ISO Standard says that it may
do either; the behavior is
implementation-defined (see question
11.33). Portable code must either take care not to call malloc(0), or be
prepared for the possibility of a null
return.
So, it's probably best to avoid using malloc(0).
One point nobody cared to talk about yet, in your first program is that realloc with length 0 is the same thing as free.
from the Solaris man page:
The realloc() function changes the size of the block pointed
to by ptr to size bytes and returns a pointer to the (possibly moved) block. The contents will be unchanged up to the
lesser of the new and old sizes. If ptr is NULL, realloc()
behaves like malloc() for the specified size. If size is 0
and ptr is not a null pointer, the space pointed to is made
available for further allocation by the application, though
not returned to the system. Memory is returned to the system
only upon termination of the application.
If one doesn't know that it can be a source of bad surprise (happened to me).
See C99, section 7.20.3:
If the size of the space requested is
zero, the behavior is
implementationdefined: either a null
pointer is returned, or the behavior
is as if the size were some nonzero
value, except that the returned
pointer shall not be used to access an
object.
This is valid for all three allocation functions (ie calloc(), malloc() and realloc()).
I think it depends.
I checked the Visual Studio 2005 sources and saw this in the _heap_alloc function:
if (size == 0)
size = 1;
I think that in many cases you may want a valid pointer, even when asking for zero bytes.
This is because this consistent behavior makes it easier to check your pointers because: if you have a non-NULL pointer it's OK; if you have a NULL pointer you probably have a problem.
That's why I think that most implementations will return a valid pointer, even when asking for zero bytes.
If malloc(0) returns dummy pointer, then how does following works:
void *ptr = malloc(0);
printf("%p\n", realloc(ptr, 1024));
I don't know what you mean by "dummy pointer". If malloc(0) returns non-NULL, then ptr is a valid pointer to a memory block of size zero. The malloc implementation saves this information in an implementation-specific way. realloc knows the (implementation-specific) way to figure out that ptr points to a memory block of size zero.
(How malloc/realloc/free do this is implementation-specific. One possibility is to allocate 4 bytes more than requested and store the size just before the memory block. In that case, ((int *)ptr)[-1] would give the memory block size, which is 0. You should never do this from your code, it's only for use by realloc and free).

Resources