How to properly allocate memory using malloc in C - c

I have a void pointer and I need to properly allocate memory of correct type. Say:
char * array="20080101"
Now, I know the value that this char string contains is a long type. Now, I have a void pointer with me:
void* pointer;
I need to allocate correct amount of memory to it and cast it as a long pointer so it will point to a long value (20080101);
The question is how do we do that? From my research, I know I can allocate it using malloc as:
void *pointer=(long*) malloc(sizeof(long) OR sizeof(long)*strlen(array));// what should be the correct parameter.
How do we make it point to a value of long type? We have our array in string.

Oh, you are a bit confused. First, A pointer, is a pointer, is a pointer, not a long and short pointer (anymore) and they are all the same size (generally 8-bytes on x86_64 and 4-bytes on x86).
Your array points to a null-terminated string literal, containing an apparent encoded date of Jan. 1, 2008. The numeric value 20080101 is easily within the size of an int or unsigned on any system and that is irrelevant to allocating storage for it (unless you are on a `16-bit system).
If you want to convert the string to a long, you can use strtol, e.g.:
long myval = strtol (array, NULL, 10);
for base 10 conversion. The second parameter (above NULL) is actually an endptr that on successful conversion returns a pointer to the next character in array following the number converted (if the string contains additional characters). You will need to include <stdlib.h> to use strtol.
As for your cast question, if you have array and it is passed as void, e.g.
long *somefunction (void *value, long *myval, ...)
Inside some function, you will need to do two things for conversion:
*myval = strtol (value, NULL, 10);
return myval;
Or, if you just need to create a pointer to long from myval, simply create the pointer:
long *lpointer = &myval;
Allocating Storage for array
When you allocate storage dynamically for any string, you need the length of the string (+ 1 for the null-terminator). Here is where you need to understand what sizeof will return and what strlen will return. If you take sizeof anypointer, you do not get the length, you get the pointer size (8-bytes, etc..). When you use sizeof dereferenced pointer you get the type size for the type pointed to (e.g. sizeof *somelongpointer will give you the storage size for a long on your system)
If you are copying the string, it is better to include <string.h> and then:
size_t len = strlen (array);
Then you are ready to allocate storage:
char *mycopy = malloc (len * sizeof *array + 1);
strncpy (mycopy, array, len * sizeof *array + 1);
mycopy then holds the contents of array. Since it was dynamically allocated, you should free it when you no longer need it (e.g. free (mycopy);)
If your intent was to create a pointer to type long and dynamically allocate storage for the long, then you need sizeof to determine the size of a long on your system. e.g.
long *mylong = malloc (sizeof *mylong);
then, (using the same somefunction example):
*mylong = strtol ((char *)value, NULL, 10);
return mylong;
Sorry for the confusion, but that should about cover all cases :).

If you really want to allocate enough memory to hold a long integer, you can do
long* value = malloc(sizeof(*value));
and then assign to it as #David says:
*value = strtol(array, NULL, 10);
However, it is usually simpler to use a local variable to hold integers, not allocate them from the heap.

Related

inserting elements to a dynamically allocated array [duplicate]

I was getting realloc(): invalid next size for a program. So I just coded this to understand what's happening.
#include <stdio.h>
#include <stdlib.h>
int main()
{
char *inp;
printf("%lu ",sizeof(inp));
char *res = (char*)malloc(15*sizeof(char*));
printf("%lu ",sizeof(res));
res = "hello world";
printf("%lu\n",sizeof(res));
return 0;
}
And surprisingly it outputs 8 8 8. Can anyone explain why is it like that? Why is it 8 by default? And how malloc() effects size of inp?
sizeof(inp) gives you the size of pointer (8 bytes, 64-bits), not the storage under that pointer.
You are using sizeof.returns size in bytes of the object representation of type. Remember sizeof is an operator.
Now sizeof is returning here 8 a constant type of size_t
Why isn't it changing? because in all tha cases you are using the same type that is char *.
Here 8 bytes is the size of the character pointer that is 64 bit.
You can probably have a look at this-
printf("size of array of 10 int: %d\n" sizeof(int[10]));
This will give the output:40. 40 bytes.
And malloc will never affect the size of a char*. It still needs 64 bits to store an address of a dynamically allocated space from heap.
Is it possible to determine size of dynamically allocated memory in c?
There is no standard way to do this. You have to take this overhead on your own. You may find some extensions to the compiler that may accomplish this.
sizeof(inp) in your case is sizeof(pointer) and hence sizeof(char-pointer) on your system is 8 bytes which is a constant. While allocating memory using malloc() you would have specified the size so why do you need to get the size of the allocated space again?
And I see res is being initialized and not inp
****EDIT**** : The below post was written before the edit of the question.
You're missing stdlib.h, to the most, for function malloc() to work properly. After that,
Point 1:
char *res = (char*)malloc(15*sizeof(char*));
should be
char *res = malloc(15); //will also issue warning to resolve missing stdlib.h
Point no note: you should be allocating memory for chars, not char *s. Then , you should write sizeof(char), not sizeof(char *). Also, sizeof(char) is always 1 in C. So, can omit that part.
Please read: do not cast the return value of malloc() and family in C.
Point 2:
strings are not supposed to be assigned to already malloc()ed pointers. use strcpy() instead.
inp = "hello world";
should be
strcpy(inp, "hello world");
Otherwise, you'll overwrite the previously allocated memory, returned by malloc(). The assignment will overwrite the memory location held by inp, causing memory leak.
Point 3.
sizeof() operator returns a value of size_t. To print that, you need %zu format specifier.
Related, from C11 standard document, chapter §7.21.6.1, paragraph 7,
z
Specifies that a following d, i, o, u, x, or X conversion specifier applies to a
size_t or the corresponding signed integer type argument; or that a
following n conversion specifier applies to a pointer to a signed integer type
corresponding to size_t argument.
Then, to answer the query about the output, in all the cases, you're printing sizeof(inp) which is essentially sizeof(char *) and that value is fixed for a particular platform (8, in your case).
Just FYI, sizeof() is an operator, it's not a function. It returns the size of the datatype, not the amount of space pointed by the variable.

Should I change the pointer to an array?

for (int a=0; a<10; ++a) {
printf ("%d", a);
}
char *foo;
foo = (char*)malloc(a);
I want to store more than one char value in foo variable.
Should I change it to an array, since the buffer is only allocating 1 char length?
Is 1 the longest length that can be stored in this buffer?
Well, foo now points to some useable address of a bytes, because this is how malloc() works. It doesn't matter if its type is char *, void * or anything else, you can only use a bytes.
Here, you increment a to 10. That means you can store 10 bytes, being 10 chars, (because in the context of C, 1 char = 1 byte), starting at the address where foo points to. Using a pointer or an array is strictly equivalent.
Since the buffer is only allocating 1 char length...
No, it is not the case here.
Quoting from the C11 standard, chapter §7.22.3.4, The malloc function
void *malloc(size_t size);
The malloc function allocates space for an object whose size is specified by size and
whose value is indeterminate.
So, in case of
foo = malloc(a); //yes, the cast is not required
a memory of size same as the value of a will be allocated, considering malloc() is successful.
Simply put, if I write a snippet like
int * p = malloc(10 * sizeof*p);
then, I can also write
for (int i = 0; i < 10, i++)
p[i] = i;
because, I have allocated the required memory for 10 ints.
That said, please see this discussion on why not to cast the return value of malloc() and family in C..
There are a couple of things you could do in a case like this.
If you know at compile time how many chars you want to store you could make it an array char foo[10]; If you know that there is always going to be 10 (or less) characters you want to store.
If you are not sure how many chars it needs to hold at compile time you would typically do dynamic allocation of memory using malloc. Now when using malloc you specify how many bytes of memory you want so for 12 chars you would do malloc(12) or malloc(12 * sizeof(char)). When using malloc you need to manually free the memory when you are done using it so the benefit of being able to ask for arbitrary (within limits) sizes of memory comes at the cost of making memory management harder.
As a side note: You typically do not want to cast the return value of malloc since it can hide some types of bugs and void *, that malloc returns can be implicitly cast to any pointer type anyway.

C: Acces bytes in mallocated memory

I have allocated array of void
I need to acces bytes of allocated memory
void* array = (void*) malloc(12);
array[0] = 0;
It returns me this error:
main.c:9: error: invalid use of void expression
array[0] = 0;
^
Is there any way how to do it ?
Thanks!
Your array is a void-pointer. And void (in C) means 'has no type'. So when you dereference it (like array[0]) the compiler has no idea what that means.
To access bytes you need a char type, which is actually the C-equivalent of a byte (a remnant from the days when characters would still fit into (8-bit) bytes).
So declare your array as:
char * array = malloc(12);
Also note that you don't have to cast the result of malloc (especially in your case since it already returns a void *). And, if you want just the 12 bytes and only use them locally (within the function or translation-unit that declares it) then you can just use a 'proper array':
char array[12];
This has the added bonus that you don't need to free it afterwards.
You need to use char or unsigned char rather than void to access the bytes:
char *array = malloc(12);
array[0] = 0;
malloc() returns a void pointer because it doesn't know the type you're allocating. You can't access the memory via that void pointer; you need to tell the compiler how to treat the block of memory. To treat it as bytes, use char or unsigned char.

C memory allocating - char* and char sizeof

What form is correct in allocating string in C?
char *sample;
sample = malloc ( length * sizeof(char) );
or
sample = malloc ( length * sizeof(char*) );
Why does char* take 4 bytes when char takes 1 byte?
Assuming the goal is to store a string of length characters, the correct allocation is:
sample = malloc(length + 1);
Notes:
Don't use sizeof (char), since it's always 1 it doesn't add any value.
Remember the terminator, I assumed (based on name) that length is the length in visible characters of the string, i.e. the return of strlen() will be length.
I know you didn't, but it's worth pointing out that there should be no cast of the return value from malloc(), either.
The reason char * is larger is that it's a pointer type, and pointers are almost always larger than a single character. On many systems (such as yours, it seems) they are 32 bit, while characters are just 8 bits. The larger size is needed since the pointer needs to be able to represent any address in the machine's memory. On 64-bit computers, pointers are often 64 bits, i.e. 8 characters.
Why does char* take 4 bytes when char takes 1 byte?
Because you are on a 32-bit systems, meaning that pointers take four bytes; char* is a pointer.
char always takes exactly one byte, so you do not need to multiply by sizeof(char):
sample = malloc (length);
I am assuming that length is already padded for null termination.
sample = malloc ( length * sizeof(char) );
First is the correct one if you want to allocate memory for length number of characters.
char* is of type pointer which happens to be 4 bytes on your platform. So sizeof(char*) returns 4.
But sizeof(char) is always 1 and smae is guaranteed by the C standard.
In the given cases you are doing two different things:
In the first case : sample = malloc ( length * sizeof(char) );
You are allocating length multiplied by the size of type char which is 1 byte
While in the second case : sample = malloc ( length * sizeof(char*) );
You are allocating length multiplied by the size of pointer to char which is 4 byte
on your machine.
Consider that while case 1 remains immutable, on the second case the size is variable.
sample = malloc(length);
is the right one
char* is a pointer, a pointer uses 4 bytes (say on a 32-bit platform)
char is a char, a char uses 1 byte
In your case, you want to alloc an array of length characters. You will store in sample a pointer to an array of length times the size of what you point to. The sizeof(char*) is the size of a pointer to char. Not the size of a char.
A good practice is
sample = malloc(length * sizeof(*sample));
Using that, you will reserve length time the size of what you want to point to. This gives you the ability to change the data type anytime, simply declaring sample to be another kind of data.
int *sample;
sample = malloc(length * sizeof(*sample)); // length * 4
char *sample;
sample = malloc(length * sizeof(*sample)); // length * 1
Provided the length already accounts for the nul terminator, I would write either:
sample = malloc(length);
or:
sample = malloc(length * sizeof(*sample));
sizeof(char*) is the size of the pointer, and it is completely irrelevant to the the size that the allocated buffer needs to be. So definitely don't use that.
My first snippet is IMO good enough for string-manipulation code. C programmers know that memory and string lengths in C are both measured in multiples of sizeof(char). There's no real need to put a conversion factor in there that everybody knows is always 1.
My second snippet is the One True Way to write allocations in general. So if you want all your allocations to look consistent, then string allocations should use it too. I can think of two possible reasons to make all your allocations look consistent (both fairly weak IMO, but not actually wrong):
some people will find it easier to read them that way, only one visual pattern to recognise.
you might want to use the code in future as the basis for code that handles wide strings, and a consistent form would remind you to get the allocation right when the length is no longer measured in bytes but in wide chars. Using sizeof(*sample) as the consistent form means you don't need to change that line of code at all, assuming that you update the type of sample at the same time as the units in which length is measured.
Other options include:
sample = calloc(length, 1);
sample = calloc(length, sizeof(char));
sample = calloc(length, sizeof(*sample));
They're probably fairly pointless here, but as well as the trifling secondary effect of zeroing the memory, calloc has an interesting difference from malloc that it explicitly separates the number and size of objects that you're planning to use, whereas malloc just wants the total size.
For any type T, the usual form is
T *p = malloc(N * sizeof *p);
or
T *p;
...
p = malloc(N * sizeof *p);
where N is the number of elements of type T you wish to allocate. The expression *p has type T, so sizeof *p is equivalent to sizeof (T).
Note that sizeof is an operator like & or *, not a library function; parentheses are only necessary if the operand is a type name like int or char *.
Please visit this Linkhttps://www.codesdope.com/c-dynamic-memory/for understand how it allocat the memory dynamically at run time. It might be helpful to understand the concept of malloc and how it allocate the amount of memory to the variable.
In your example;
char *sample;
sample = malloc ( length * sizeof(char) );
here, you are declare a pointer to character for sample without declaring how much memory it required. In the next line, length * sizeof(char) bytes memory is assigned for the address of sample and (char*) is to typecast the pointer returned by the malloc to character.

Confused with results of sizeof() function

I'm trying to write a function that converts a base 10 integer to a binary number.
I am constructing the function like this:
void dec2bin(int dec, char * bin);
The function will store the binary result by means of the pointer in the argument. It is passed a variable declared elsewhere as follows:
char *r1 = (char *)malloc(24);
The first thing the function has to do is fill the "24 bit result" with all zeros. It works great now since I've coded it based on me knowing the "size," but I can't figure out how to determine the "size" of an arbitrary "r1". Every way I can think to use the sizeof function does not give me 24.
I am confused at this point, and not connecting the relationship between the respective sizes of a char, char*, etc and how I can use those sizes to get what I'm looking for with respect to "r1".
Would someone mind giving me a pointer? Pun intended.
Thanks!
You may just pass the size as another parameter:
void dec2bin(int dec, char * bin, size_t max_chars);
I can't figure out how to determine the "size" of an arbitrary "r1".
You cannot do that: the information about the size that you passed to malloc is irreversibly lost after the call. All you have at that point is a pointer to the chunk of at least 24 bytes of memory. If you need the size, you need to store it somewhere else - for example, in a separate variable that you carry around.
Two typical work-arounds to this issue include (1) storing a zero-terminated string in the allocated space, and using the length of that string as the proxy to the size of the allocated chunk, and (2) defining your own structure that contains both the size and the allocated pointer. Neither solution is ideal, but at least the choice is with you.
The type of r1 is a char* (char pointer), so, like all pointers, its size is 4 (or 8, depending on your situation). No matter the size of the memory block you're allocating to it.
You can't retrieve the size of the allocated block from a pointer, so if you need the size later, you will have to remember the size yoursef (e.g. by storing it in a different variable).
r1 is a variable of pointer type, and its size is fixed and always the same (just like the size of any variable of a given type), which is no larger than (and usually equal to) sizeof(void *). What you really want to know is the size of the array that's sitting at *r1 (note the asterisk), and that is something you cannot know. You have to keep track of it yourself, typically like this:
size_t const n = get_some_number();
foo * p = calloc(n, sizeof(foo));
Now you use the pair (p, n) to describe your dynamic array.
(Note that C99 and C11 have the notion of a variable-length array, in whose context sizeof does actually (sometimes) give you the actual array size, but that's a somewhat murky affair, and in any case it isn't what you asked for.)
When you allocate memory, you get back a pointer, which has a fixed size, so there's no way to get the size of the allocated memory with sizeof.
As others have said, if it's just a pointer, you won't be able to tell anything (unless it's zero-terminated, in which case you can just iterate until you hit an element equal to zero (not the character '0')).
However, if you set it up as follows, you can actually see the buffer size after calling sizeof()... at least until you send it to a function, where the array decays to a plain char* pointer.
void test( char* s )
{
int i2 = sizeof( s ) / sizeof( char );
}
char c1[] = "Testing!";
int i1 = sizeof( c1 ) / sizeof( char ); // i1 is 9 (size of buffer)
test( c1 ); // i2 is 4 (size of pointer)

Resources