-3

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.

Misa Lazovic
  • 2,805
  • 10
  • 32
  • 38
Sunil Sharma
  • 21
  • 1
  • 4
  • 1
    Cast back to a char pointer and use `atol()` to get the `long int` stored in the string. – owacoder Oct 19 '15 at 18:37
  • we see that you are a little bit confused, you may not know what really you want. tell us your plan from allocating a pointer to a long that hold a single value. and then maybe we can give a more suitable solution. or at least we can advise you in better way. – milevyo Oct 19 '15 at 18:52
  • "char string contains is a long type" is incorrect. `array` is a pointer to `char`. – chux - Reinstate Monica Oct 19 '15 at 18:54
  • "How to properly allocate memory using malloc in C" – first, drop the cast. [it only causes harm](https://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc/605858#605858). – The Paramagnetic Croissant Oct 19 '15 at 18:58

2 Answers2

1

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 :).

David C. Rankin
  • 81,885
  • 6
  • 58
  • 85
  • Although pointers are not long or short, I think the OP may have meant "pointer to long integer" when he said "long pointer". – AShelly Oct 19 '15 at 18:45
  • Thank you very much for the clarification. Moreover, if I need to allocate memory for that string. Should I use only sizeof(the type of the variable) or sizeof(strlen(string)*sizeof(type)). This always confuses me. what should be the correct parameter. My guess is sizeof(type). – Sunil Sharma Oct 19 '15 at 18:48
  • Rule of thumb: Always allocate the size of the thing will are assign to. i.e `sizeof(long int)`, not `strlen(input)`. The only time the size of the source data matters is if you are trying to reserve enough memory for an exact copy. – AShelly Oct 19 '15 at 18:53
  • Minor point: "... numeric value 20080101 is easily within the size of an `int` or `unsigned` on any system". Many systems of 2015 use 16-bit `int`, which is valid C. – chux - Reinstate Monica Oct 19 '15 at 18:57
  • @AShelly Well, now we are unclear again, do we want to copy the string or dynamically allocate for a long pointer? I'll add that too... – David C. Rankin Oct 19 '15 at 18:57
  • There is no need to cast a `void*` to any other object pointer type. `void*` already says that this is a pointer to an object of unspecified type, it converts implicitly to any other pointer type. – Jens Gustedt Oct 19 '15 at 19:06
  • Then, it seem to me that you are suggesting to return the address of a local variable? This would be a serious programming error. – Jens Gustedt Oct 19 '15 at 19:06
1

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.

AShelly
  • 34,686
  • 15
  • 91
  • 152