Is the pointer calloc function return a pointer vector? (C language) - c

I'm trying to understand a c code, (SimpleScalar, bpred.c), there is the thing that confuses me a lot:
int *shiftregs;
shiftregs = calloc(1, sizeof(int));
int l1index, l2index;
l1index = 0;
l2index = shiftregs[l1index];
I delete some code that might not help. After the calloc call, *shiftregs becomes a pointer array? And what is the value of l2index? Thanks a lot!

Since shiftregs is a pointer to an int, *shiftregs is an int.
Since calloc guarantees that the memory it allocates is set to 0, and you've allocated enough memory to refer to shiftregs[0], l2index will be 0 (assuming calloc didn't fail and return NULL).

The calloc() function is being used to allocate a dynamic array of zeroed integers that can be referenced via the pointer shiftregs.
The value in l2index is going to be zero unless the allocation failed (calloc() returned NULL). If the allocation failed, you invoke undefined behaviour; anything could happen, but your program will probably crash. Check the allocation so that it doesn't crash!

l2index is 0. calloc set memory to zero. Following is Linux Programmer's Manual:
calloc() allocates memory for an array of nmemb elements of size
bytes each and returns a pointer to the allocated memory. The memory
is set to zero. If nmemb or size is 0, then calloc() returns
either NULL, or a unique pointer value that can later be successfully
passed to free().

Check if the calloc() return NULL.
If so, the "l2index = shiftregs[l1index];"will crash, for you try to get value from a NULL point(shiftregs).
If not, as they said l2index will be 0.

Related

Can I realloc() an unallocated pointer?

Normally, realloc() is used to reallocate a previously allocated pointer:
int *DynamicArray = malloc(sizeof(int)*SomeArbitraryValue);
// Some rando code where DynamicArray is used
DynamicArray = realloc(DynamicArray, sizeof(int)*SomeOtherArbitraryValue)
But can realloc() be used to directly allocate memory? As in
int *DynamicArray = realloc(/*...*/);
Can realloc() handle non-preallocated pointers?
Yes, just pass NULL to it's first argument.
The manpage of realloc(3) says ...
The realloc() function changes the size of the memory block pointed to by ptr to size bytes. The contents will be unchanged in the range from the start of the region up to the minimum of the old and new sizes. If the new size is larger than the old size, the added memory will not be initialized. If ptr is NULL, then the call is equivalent to malloc(size), for all values of size; if size is equal to zero, and ptr is not NULL, then the call is equivalent to free(ptr). Unless ptr is NULL, it must have been returned by an
earlier call to malloc(), calloc(), or realloc(). If the area pointed to was moved, a free(ptr) is done.
As the answer by #ZhangBoyang tells you, yes, assuming one possible interpretation of your question. However the way you've worded your question ("non-preallocated pointers") suggests you may have misunderstanding of some of the concepts involved. malloc does not "allocate pointers". It allocates objects, and pointers are values that point to objects. The lifetime of those objects are not connected to the lifetime of any particular pointer pointing to them.
Passing a pointer to realloc doesn't "do anything to" the pointer. It does something to the object pointed to by it. If the pointer is uninitialized or invalid, the call has undefined behavior and bad things will happen. If the pointer is a null pointer, however, realloc(ptr, n) will behave exactly as malloc(n).

Initialization of malloc & calloc

Why does malloc always initialize with garbage values and calloc always intialize with 0? Any reason behind it?
Why can't we use realloc instead of malloc for dynamic memory allocation?
After reallocating memory dynamically, what are initial values of it?
Code:
int *ptr;
ptr = (int *) realloc(ptr,50);
printf("%d",*ptr);
malloc is made to just allocate memory of the specified size. calloc does the same (with different parameters), but is also designed to zero initialize the memory. It is just how they are designed.
You can use realloc for dynamic reallocation, but it is used to reallocate, which in your example it is not. realloc can only be used on memory already initialized with malloc, calloc, or realloc, or if the pointer is NULL then it is equivalent to malloc
Why does Malloc always initialize with Garbage values & Calloc always intialize with 0?
This behaviour is defined by the C standard.
In fact malloc() does not initialise the memory allocated at all. This mostly is for performance reasons. Do not read it, before having written to it yourself, to not provoke UB.
calloc() is specified to initialise the memory allocated to all 0s.
why can't we use realloc instead of malloc for dynamic memeory allocation.
You can. Just pass NULL as 1st parameter.
Your example adjusted:
int *ptr = NULL;
ptr = realloc(ptr, 50);
*ptr = 42;
printf("%d\n", *ptr);
prints:
42

What if NULL and size 0 are passed to realloc()?

Is the behavior implementation defined? If NULL and size == 0 are passed to realloc():
int main(void)
{
int *ptr = NULL;
ptr = realloc(ptr, 0);
if(ptr == NULL)
{
printf("realloc fails.\n");
goto Exit;
}
printf("Happy Scenario.\n");
Exit:
printf("Inside goto.\n");
return 0;
}
The above code should print "realloc fails", right? But it is not? I've read somewhere that this call to realloc may return NULL also. When does that happen?
This behavior is implementation defined.
From the C standard:
Section 7.22.3.5 (realloc):
3 If ptr is a null pointer, the realloc function behaves like the malloc function for the specified size. Otherwise, if ptr
does not match a pointer earlier returned by a memory management
function, or if the space has been deallocated by a call to
the free or realloc function, the behavior is undefined. If
memory for the new object cannot be allocated, the old object is
not deallocated and its value is unchanged.
So realloc(NULL, 0) is the same as malloc(0)
If we then look at section 7.22.3.4 (malloc):
2 The malloc function allocates space for an object whose size is specified by size and whose value is indeterminate.
3 The malloc function returns either a null pointer or a pointer to the allocated space.
The standard does not state what happens when 0 is passed in.
But if you look at the Linux man page:
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().
It explicitly states that the returned value can be freed but is not necessarily NULL.
In contrast, MSDN says:
If size is 0, malloc allocates a zero-length item in the heap and
returns a valid pointer to that item. Always check the return from
malloc, even if the amount of memory requested is small.
So for MSVC, you won't get a NULL pointer.
realloc(3) doc:
If ptr is NULL, then the call is equivalent to malloc(size), for all values of size
malloc(3) doc:
If size is 0, then malloc() returns either NULL, or a unique pointer value that can later be success‐fully passed to free().
So yes, it is implementation defined, you'll either get null or a pointer you can free.
The call
realloc(NULL, size);
is equivalent to
malloc(size);
And what malloc() does when asked to allocate 0 bytes is a bit unclear, the standard doesn't say. I think it's implementation-defined. It basically "doesn't matter"; either it returns NULL, or it returns a pointer where you can legally access zero bytes, those are pretty much alike. Both can be passed to free().

What address malloc and calloc returns?

Is the malloc or calloc returns pointer which specifies the exact location of data to be stored?
See here
The malloc() and calloc() functions return a pointer to the allocated
memory, which is suitably aligned for any built-in type. On error,
these functions return NULL. NULL may also be returned by a
successful call to malloc() with a size of zero, or by a successful
call to calloc() with nmemb or size equal to zero.
It returns an address which is valid in the current process.

C realloc() function fails

Why does this code not work?
char *x=malloc(100);
x++;
x=realloc(x, 200);
I mean x is a valid string pointer, just incremented by one?
See C Standard (C99, 7.20.3.4p3) on realloc and my emphasis:
void *realloc(void *ptr, size_t size);
If ptr is a null pointer, the realloc function behaves like the malloc function for the
specified size. Otherwise, if ptr does not match a pointer earlier returned by the
calloc, malloc, or realloc function, or if the space has been deallocated by a call
to the free or realloc function, the behavior is undefined.
In your case x was returned by malloc, not x + 1. So your program invokes undefined behavior.
Think about what realloc does. How can it free the pointer at address x+1 when malloc actually created a pointer at address x?
In more concrete terms, let's assume you allocated 100 bytes at address 0x1000. Now x is incremented, pointing at 0x1001. Then you call realloc at the new address. Because none of malloc, calloc, and realloc created 0x1001, free (or equivalent code) used by the call to realloc has no idea how to do anything with 0x1001; it can't even fathom how many bytes of memory it occupies. It only knows about the 100 bytes at 0x1000.
The basic idea behind implementations of malloc and friends is that you keep track of the pointers assigned and how many bytes were allocated. Then when free is called later, the pointer passed to free is looked up. If there is no reference to that pointer passed to free, what else is there to do except crash? That, to me, is more logical than supposing you can keep using a pointer that may or may not be valid.
char *x=malloc(100);
x++;
x=realloc(x, 200);
In the code shown above the address pointed by the pointer x is changed before invoking the realloc() function. This is undefined behavior in C.
This is an undefined behavior as you if you think that you have obtained a pointer from malloc() which is wrong.
Clearly x was returned by malloc and its value was changed before calling realloc() Hence it is showing the undefined behavior.

Resources