char **three = (char**)malloc(sizeof(char*));
char**, the char pointer type is used. and char** means I'm dereferencing char pointer. and as for the sizeof(char*) I'm using the size of char pointer which is 8 byte.
Am I misunderstanding this?
So the code:
char **three = ( char** )malloc( sizeof( char* ) );
Allocates an array of pointers-to-char, but with only a single element. The variable three is a pointer-to, a pointer-to a char. Much the same as:
char *three[1];
Normally (as #paxdiablo points out), it would be more usual to allocate a number of pointers:
int line_count = 66;
char **three = ( char** )malloc( line_count * sizeof( char* ) );
Once allocated, this can be used with array notation:
three[0] = "The Owl and the Pussy-cat went to sea";
three[1] = "In a beautiful pea-green boat,";
three[2] = "They took some honey, and plenty of money,";
three[3] = "Wrapped up in a five-pound note."
There's nothing particularly special about a char**, every C/C++ program gets one as its argv.
As a programmer, you don't really know that your pointer is 8 bytes, you know the pointer will be some size. This is where the sizeof( char* ) comes in. During compilation the compiler swaps this with the real value. That way when the architecture is 16, 32 or 64 bit (or maybe 128 bit in the future), the code still compiles fine.
Let's see if we can break this down:
char **three = (char**)malloc(sizeof(char*));
[ 1 ][5][ 4 ][ 3 ] [ 2 ]
Create a variable three of type char **, a pointer to a char * (often a "string" in C).
Use the size of a char* to pass to malloc.
Use malloc to allocate that many bytes.
Cast the return value from malloc, a void*, to char**.
Assign that value to three.
So in terms of where I think your misunderstanding lies:
Do not cast the return value of malloc or realloc in C. C is perfectly capable of implicitly casting void* to other pointer types and doing it explicitly can hide certain subtle errors.
There is no dereferencing going on here. The (unwise) cast is exactly that, telling the compiler you want to treat an expression of one type as if it was another type.
You've actually allocated an array of char* variables and that array size is one. So, short of calling realloc on it at some point, its use is limited (unless you need it to survive the current scope, you're probably just better using a local variable rather than an allocated one-element array).
Related
I'm trying to document some code to improve my knowledge of pointers and general ANSI C ability.
...
int static_store = 30;
const char * pcg = "String Literal";
int main()
{
int auto_store = 40;
char auto_string[] = "Auto char Array";
int * pi;
char * pcl;
pi = (int *) malloc(sizeof(int));
*pi = 35;
pcl = (char *) malloc(strlen("Dynamic String") + 1);
strcpy(pcl, "Dynamic String");
...
From first looks, two pointers are initialised, pi and pcl, of type int and char respectively.
But the lines after are confusing to me and I don't understand what is happening. I can see that malloc is being called to allocate memory the size of int (40). Is it assigning memory to the variables pi and pcl?
Is it assigning memory to the variables pi and pcl?
Yes malloc is allocating memory to these pointers.
pi is allocated memory equal to sizeof(int)(that may vary) and pcl has be allocated memory equal to length of string plus 1(plus 1 for null character).
From first looks, two pointers are initialised, pi and pcl, of type int and char respectively
They are declared not initialized.
Note- Please don't cast return of malloc
2 pointers are delcared (pi and pcl). At declaration they are not intialized.
pi is then pointed to a block of heap allocated memory that can hold 1 int (the size of this is platform dependant but it would usually be 4 bytes) allocated with the fucntion maloc. Somewhere this memory will have to be explicitely freed with the funtion free - failing to do so will be a memory leak.
The int value 35 is then stored at that memory location. *pi can be read as "what the pointer pi points to" it is effectively the same as pi[0].
pcl is then pointed to a block of heap allocated memory that is large enough to hold 14 char plus a '\0' char (i.e 15 bytes) using the function malloc (as above at some point this memory must be freed).
The 15 characters "Dynamic String\0" is then put in that memory using the function strcpy.
The line:
pi = (int *) malloc(sizeof(int))
Actually allocate memory for one int variable. The line afterwards, puts the value 35 into that variable.
The line:
pcl = (char *) malloc(strlen("Dynamic String") + 1)
Creates a dynamically allocated char array (which is equivalent to a string). The size of that array is of the length of the string ("Dynamic String") plus one. The next line copies the string: "Dynamic String" into the allocated array. The plus one is needed because each string in c ends with the char '\0' which is a sign for the end of a string.
The malloc function reserves a block of memory in the heap (the dynamic memory pool), and returns a pointer to the first element of that block of memory. That memory is reserved until you call free, or the program exits.
In the call
pi = (int *) malloc(sizeof(int));
malloc reserves a block of memory large enough to store a single int value, and the pointer to that memory block is assigned to pi. You do not need to cast the result of malloc1, and it's actually considered bad practice2. A better way to write that would be
pi = malloc( sizeof *pi );
The expression *pi has type int, so sizeof *pi is equivalent to sizeof (int)3. The advantage of using sizeof *pi over sizeof (int) (as well as dropping the cast) is that if you ever change the type of pi (from int * to long *, for example), you won't have to change anything in the malloc call; it will always allocate the right amount of memory regardless of the type of pi. It's one less maintenance headache to worry about.
Similarly, the call
pcl = (char *) malloc(strlen("Dynamic String") + 1);
reserves enough memory to hold the contents of "Dynamic String" (the +1 is necessary for the string terminator) and assigns the pointer to that memory to pcl. Again, this would be better written as
pcl = malloc( strlen("Dynamic String") + 1 ); // no cast
sizeof (char) is 1 by definition, so you don't need an explicit sizeof *pcl in the call above; however, if you ever decide to change the type of pcl from char * to wchar_t *, it would be good to have it in place, although you'd still have to change the string literal and change how you compute the length, so it's not maintenance-free.
The general form a malloc call is
T *p = malloc( num_elements * sizeof *p ); // where num_elements > 1
or
T *p;
...
p = malloc( num_elements * sizeof *p );
There is a similar function named calloc that will zero out the allocated memory block:
T *p = calloc( num_elements, sizeof *p );
or
T *p;
...
p = calloc( num_elements, sizeof *p );
1. In C, anyway; C++ does require the cast, since C++ does not allow implicit conversions between void * and other pointer types. But you shouldn't be using malloc in C++ code, anyway.
So why do people still cast the result of malloc in C? It's largely a holdover from pre-ANSI days (more than a quarter of a century ago), when malloc returned char *, which cannot be assigned to a different pointer type without a cast. The 1989 standard introduced the void * type, which is essentially a "generic" pointer that can be assigned to other pointer types without an explicit cast.
2. Under the C89 standard, if the compiler sees a function call without having seen a declaration for that function, it will assume that the function returns int. Thus, if you forget to include stdlib.h or otherwise don't have a declaration for malloc in scope, the compiler will assume it returns an int value and generate the machine code for the call accordingly. However, int and pointer types aren't compatible, and normally the compiler will issue diagnostic if you try to assign one to the other. By using the cast, however, you supress that diagnostic, and you may run into runtime problems later on.
The 1999 standard did away with implicit int typing for functions, so that's not really a problem anymore, but the cast is still unnecessary and leads to maintenance problems.
3. sizeof is an operator, not a function; parentheses are only required if the operand is a type name like int or double or struct blah.
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.
Recently, I am trying to make good practice on C now I come to a command execution.
It tells me that I should us char**? But am I have some concept wrong.
Please help me.
Code is here
int excution(int cnt, char token[][BUFSIZE],int *t_token)
{
setenv ("PATH", "/bin:/bin/usr:", 1);
//printf("%s",getenv("PATH")); // check environement
const char *b_cd="cd";
const char *b_exit="exit";
const char *b_fg="fg";
const char *b_jobs="jobs";
int i,j,k;
//STEP 9:excute normal commanand
char args[cnt][BUFSIZE];
for(i=0;i<MAXARG;i++)
{
if(t_token[i]==COMMAND)
{
strcpy(args[0],token[i]); // copy 1st ARG
j=1;
while(t_token[i+1]==ARG)
{
strcpy(args[j],token[i+1]);
i++;
j++;
}
for(k=0;k<j;k++)
{
printf("%s\n", args[k]);
}
execvp (args[0], args);
}
}
It gives me warning in compilation. But it gives segmentation fault if I change 2D array to a char**....
warning: passing argument 2 of ‘execvp’ from incompatible pointer type
[enabled by default] /usr/include/unistd.h:579:12: note: expected
‘char * const*’ but argument is of type ‘char (*)[256]’
Maybe I'm just old, but when I see char var[X][Y] I think the compiler is going to allocate a chunk of memory of sizeof(char)*X*Y and then var[i] will be equal to var+(i*Y*(sizeof(char))). As long as everybody knows what X & Y are, all is cool. But execvp() doesn't know your X & Y sizes.
In contrast, char * var[X] will give me an array of X pointers each sizeof(char*), or a blob of memory of sizeof(char*)*X.
Now char's are generally 1 byte. char* is generally 4 or 8 bytes, but can vary depending on your system.
So char * var[X] might be a chunk of memory X*8 bytes in size, and anyone receiving var as an argument would know how to access each char* pointer in that array as pointer sizes are well known by the compiler and it's just a standard offset.
On the other hand, anyone receiving char var[X][Y] is going to be really confused. There's no way to tell where one argument ends and another begins in that giant chunk of memory.
Long story short: Use char * args[SIZE];, use arg[i] = "command" or arg[i] = token[j], and learn about pointers.
p.s. char** is a pointer to a pointer to char. (It's, say, 8 bytes that points to another memory address of 8 bytes of data that contains the memory address of a char (1-byte) value. This makes more sense when we talk about storing strings as null-terminated (char(0)) arrays of characters - e.g. sequentially stored characters, so if we know the address of the first character in the string we can just increment the pointer to get the next character until we hit zero, the null character '\0'.)
It's similar to, but not quite the same as an array of pointers to char. (Which is, say, 8 bytes that points to a memory address containing at least 8 bytes of data, perhaps N*8 bytes of sequential memory addresses (pointers). Again, just like with the sequential char array, we can have an array of char*, one stored after the other in memory.)
It would be more accurate to say a char** is roughly equal to a char*[N], only the char** doesn't allocate any memory for the internal char* pointers whereas char*[N] does - it allocate space for N char* pointers.
When receiving an array of pointers to char (char*[]), you can declare it as a pointer to a pointer to char (char**) and still iterate through the array. You just need to have the right underlying block of memory (data) located (passed in) where that pointer points to.
I've read various tutorials on pointers, and I now come with a question,
is this:
char *input = malloc(sizeof(char)*24);
the same as
char *input[24];
I was under the impression that the malloc will also create my space on the heap with 24 slots. Usually, I see char input[24], but the char *input[24] I figured was a simpler way than mallocing.
Thanks!
No, they are not the same.
char *input = malloc(sizeof(char)*24);
will allocate a block of 24 char's on the heap and assign a pointer to the start of that block to input. (technically you are just telling it to allocate x number of bytes where x is 24 times the size, in bytes, of each char)
char *input[24];
will create an array of 24 char pointers on the stack. These pointers will not point to anything (or garbage on init) as you have it written.
For the second example, you could then take each pointer in the array input and allocate something for it to point to on the heap. Ex:
char *input[NUM_STRS];
for( int i = 0; i < NUM_STRS; i++ )
{
input[i] = malloc( MAX_STR_LEN * sizeof(char) );
}
Then you would have an array of character pointers on the stack. Each one of these pointers would point to a block of characters on the heap.
Keep in mind, however, that things on the stack will be popped off when the function exits and that variable goes out of scope. If you malloc something, that pointer will be valid until it is freed, but the same is not true of an array created on the stack.
EDIT:
Based on your comment, here is an example of making 24 character pointers on the heap and allocating space for them to point to:
#define NUM_STRS 24
#define MAX_STR_LEN 32
char **input = malloc( sizeof(char *) * NUM_STRS );
for( int i = 0; i < NUM_STRS; i++ )
{
input[i] = malloc( sizeof(char) * MAX_STR_LEN );
}
Please keep in mind that with this example you will have to free each pointer in input, and then input itself at the appropriate time to avoid leaking memory.
These are not the same at all.
char *input = malloc(sizeof(char)*24);
This allocates enough memory to hold 24 char, and assigns the address to input (a pointer). This memory is dynamically-allocated, so it needs to be released at some point with an appropriate call to free().
char *input[24];
This declares input to be an array of 24 pointers. This has automatic storage, which means you do not need to free it. (However, you may need to free the things being pointed to by each of the pointers, but that's a different matter!)
Fundamentally, the types of the two variables are different. In the first case, you declare a pointer to char that points to memory dynamically allocated by malloc (which you are morally obligated to free at a later instant). In the second case, you declare an array of pointers to char.
Couple of observations:
sizeof(char) is one by definition, so you can leave that out. (No, it does not convey a documenting purpose. You are better of rewriting it as char *input = malloc( 24 * sizeof *input );)
Very seldom will the call to malloc have an integer literal. If it does (24) in your example, then usually one would prefer to have an array to hold that (there are some considerations regarding stack usage that I am side-stepping here).
hope this helps,
You can compare it better to char input[24]; (note no *). With that you can use input in the same way but the memory is on the stack instead of on the heap.
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)