char *c = (char *)malloc(30*sizeof(char));
printf("%lu \n",sizeof(c));
In the above code I am trying to print the size of 'c'. No matter what number I give instead of '30' in the code, I get the sizeof(c) as 8.
What is the problem? How can I determine the size of an array?
Is length and size the same for an array?
At the moment you are asking for the size of a pointer which on a 64 bits machine is 8 bytes. Since this is a malloc and not a real array, you can't retrieve the size of the buffer allocated through c.
If c was declared as
char c[30];
You could determine size with
size_t size = sizeof(c)/sizeof(c[0])
But to be honest if I had to do that, I would just #define the array size even though the size calculation would be stripped out at compilation. It makes the code clearer in my opinion.
You are printing the size of a char * which in your system is 8.
If you want to know the amount of memory that was "malloc"ed you must store it somewhere. In your case your should store the 30 for future use if you are going to need it.
sizeof(c) means give me the size of the variable c. Since c is a pointer it's giving you back the number of bytes that the pointer takes up in memory. The fact you're seeing 8 suggests you're compiling for 64bit. On a 32bit built it would be 4.
It's your job to remember the size of the thing you've allocated. After all, you asked for an amount of memory, so you do know how much you allocated! In your case, size_t size = 30*sizeof(char) will give you the amount you've allocated.
sizeof is an operator, not a function, thus the compiler creates the code equivalent to something like sizeof(char *) and pointer of a char (depending on the architecture of course) is of 8 bytes.
Actually sizeof(*c) will return 1. The size of a mallocced buffer cannot be determined compile time (which is what sizeof does).
You're getting the size of the variable c, not the size of the memory region it points to. There's no way to get the size of an array inside a function because it always decays to pointer. You must store the size yourself. If you've passed the size to malloc then why can't you store that size to a variable?
Related
I'm trying to improve my knowledge with pointers by making an pointer who points to another pointer that is practically a string.
Now I want to get size who normally I could get fromsizeof(foo[0])/sizeof(foo[0][0])
Pointer form
char** foo;
sizeof(test)/sizeof(*test) doesn't indicate the number of elements anymore with your declaration, because the compiler doesn't know what is the pointer pointing to, because sizeof() is a compile time operation and hence not dynamic.
To find no of elements, you can add a sentinel value:
char **test = {"New York", "Paris", "Cairo", NULL};
int testLen = -1;
while(test[++testLen] != NULL){
//DO NOTHING
}
You will never get the size of a block of memory where a pointer points to... because there can be anything.
test simply points to a place in memory where some other pointers are stored (to the first one). Each pointer will again lead to another place in Memory where some character values are stored. So, your test variable contains a simple number (the index of a place in Memory) and depending on your operating System sizeof(test) will maybe have 4 bytes or 8 bytes as result regardless of the size of the allocated memory.
sizeof() will work as you might have expected when using stack arrays. If test is declared as
char test[10][20];
Then sizeof(test) will in fact return 200.
How I can get it's length (=rows)?
You cannot. Read more in How to get the length of dynamically allocated two dimensional arrays in C
Your attempt:
char** foo;
sizeof(foo[0])/sizeof(foo[0][0])
most probably results in 8, right? That's because you are getting the size of a pointer (which is probably 8 in your system) and then divide by the size of a character, which is always 1.
If you are allocating something large you use malloc() and malloc receives one argument - the size in bytes(e.g malloc(sizeof(int)*20).
malloc also returns a void pointer to the allocated memory. You typically cast this pointer to fit your type.
In other words you can't really get the size. You must store it somewhere and pass it to other functions when its needed.
A pointer to pointer (**) is like adding one additional dimension.
[] these are more of a syntax sugar for pointer arithmetic.
a[i] would be the same as *(a+i).
This may vary on your system but sizof() will give you these values for these types.
int a; //4
int b[5]; //20
int* c; //8
int d[5][5];//100
int** e; //8
I'm trying to learn more about ways to exploit/prevent buffer overflow in my programs. I know that the following code is vulnerable if the size is constant, but what if the size is random every time? Is there still a way to grab it from the stack and somehow alter the amount of overflow characters dynamically?
void vulnFunc(int size){
char buffer[size];
gets(buffer);
// Arbitrary code
}
Consider
fgets(buf, sizeof(buf)-1, stdin);
with stdin and a size that matches your buffer. It will be safe. There are other possibilities, such as a loop with getc(stdin): when the data becomes larger than
your buffer you can realloc().
It depends on the variable that is used to represent the array, if its of type char[] or char *. let me explain why:
for char[], the variable name represents an array and the sizeof operator returns the size of the array in the memory (number of cell * sizeof(type)), so basicly you can get the number of cells using the following call:
sizeof(array)/sizeof(array[0])
for char*, the variable is a pointer which holds the value of the first cell of the array, sizeof(array) in this case will return the size of pointer in memory that is 8Byte for 64bit architecture, it has nothing with the array so you cant get the information from this kind of variable. Maybe you could store the size of the allocated buffer in memory but I don't know if it suits your needs.
I am assigning a new memory chunk to a pointer, but apparently the size of the chunk is not the one which I pass as a parameter to malloc
char *q="tre";
printf("q in main %zu\n", sizeof(q));
q = (char*)malloc(6);
printf("q in main %zu\n", sizeof(q));
Outputs
8
8
The pointer however does point to a new memory chunk.
How is this possible?
sizeof returns size of pointer, in your case it is (char*), it will not give the memory allocated by the malloc. Keep the memory size in separate variable for later use.
char *q;
printf("%zu\n", sizeof(q));
sizeof(q) refers to the size of the pointer, not the amount of memory it points to.
What you are obtaining is the size of the variable q as a pointer type. In general all pointers will have the same size in your program.
Since 8 bytes are 64 bits, it seems you are doing 64-bit applications. :)
sizeof(q) returns the size of the pointer q which will on a 64 bit machine be 8 bytes, not the size of the memory block allocated at that pointer. sizeof is a compile time not a runtime operation.
I'm not clear what you want to do here, but if you want to allocate enough memory for a string at location s, then you want to malloc(strlen(s)+1) (+1 for the terminating NULL).
Perhaps you want to get the size of malloc()ed block. There is not a portable way to do this to my knowledge, but malloc_usable_size nearly does it on glibc. From the man page:
malloc_usable_size() returns the number of bytes available in the dynamically allocated buffer ptr, which may be greater than the requested size (but is guaranteed to be at least as large, if the request was successful). Typically, you should store the requested allocation size rather than use this function.
Note the last sentence.
I am refreshing my C skills. I am using a char *s and using malloc to allocate memory to the s. Then using scanf, I read the input to s. But my question is I haven't specified a size for the memory chunk. But the program works. How does the memory gets allocated for the arbitrary length of the input string? Is scanf simply incrementing the pointer and writing data into the location?
#include <stdio.h>
#include <stdlib.h>
int main() {
char *s;
s = (char *) malloc(sizeof(s)); //I did not specify how much like malloc(sizeof(s) * 128)
if (s == NULL) {
fprintf(stderr, "\nError allocating memory for string");
exit(1);
}
scanf("%s", s);
puts(s);
free(s);
return 0;
}
/*
Input:
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
Output:
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
*/
With char *s;, sizeof(s) is the same as sizeof(char *) which is either 4 or 8 depending on whether you are on a 32 bit box or a 64 bit box.
IF you are on a 32 bit box then you can store 3 characters plus the null 'end of string' character. IF you store more it may explode.
sizeof(s) returns the size in bytes of s which is of type char*. Typically on a 32 but machine this is 4 bytes and 8 byts on a 64 bit machine. So you actually have told malloc the number of bytes to allocate and s will point to that region of memory.
You did specify a size: sizeof(s). Since s is a char *, sizeof(s) == sizeof(char *). Depending on your platform, this may be 4 or 8 bytes in length.
So, you've effectively allocated 4 (or 8) bytes to store a string. If you type more than 3 (or 7) characters on the command line, then you are going to start writing past the end of the allocated array, which triggers undefined behaviour. With undefined behaviour, anything could happen: your program might look like it works fine, the program might fill the rest of the memory with ZALGO, the program might segfault horribly, or you might encounter the ever-popular nasal demons. The C specification does not specify what happens (hence the term "undefined behaviour").
The fact that your program "works" at all is a complete fluke, and should never be relied upon.
sizeof(s) is you case returns the size of a character pointer, which will be 4 or 8 bytes depending on if you are running on a 32 or 64 bit platform.
You want to use sizeof(*s) instead. However, since the C standard specifies that sizeof(char) (which is what sizeof(*s) will be) is one, so for character arrays you don't need it.
it will only allocate the space =size of char * and than
simply incrementing the pointer and writing data into the location? as you thought.
the answer for why it works is: because its writing it on the memory area which is not allocated to you but if the area is reserved by some other process your program will crash. so better allocate a larger space.
You are only allocating memory of size equal to size of Integer. If you write strings of greater length to this variable, it will just overwrite the existing memory locations and well, your program will show unexpected behavior.
I am curious why I am getting the following behaviour in my code.
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
int M=24;
int arr[M];
int N=24;
int* ptr=(int*) malloc(sizeof(int)*N); /*Allocate memory of size N */
printf("Size of your malloced array is %lu\n",sizeof(ptr)/sizeof(ptr[0])); /* Get the size of memory alloctaed. Should be the same as N?*/
printf ("Size of your normal arrays is %lu\n",sizeof(arr)/sizeof(arr[0])); /* Ditto */
free(ptr);
return 0;
}
The output is
Size of your malloced array is 2
Size of your normal arrays is 24
I would have thought the output would be 24 in both places. How then does one get the size of the malloced array If somehow I have "forgotten" it?
Surely the pointer ptr will contain some information about the size of the malloced array since when we call free(ptr) it will release the array just malloced
When you use sizeof() on a pointer, you get the size of the pointer. Not the size of the allocated array. In your case, a pointer is probably 8 bytes and an int is 4 bytes, hence why you get 2.
In short, you can't get the size of an allocated array. You need to keep track of it yourself.
EDIT : Note that some compilers do actually support this functionality as an extension:
For example, MSVC supports _msize(): http://msdn.microsoft.com/en-us/library/z2s077bc.aspx
While sizeof() works as you'd expect with fixed-length and variable-length arrays, it doesn't know anything about the sizes of malloc()'ed arrays.
When applied to a pointer, sizeof() simply returns the size of the pointer.
More generally, given a pointer to a malloc()'ed block, there's no standard way to discover the size of that block.
See C FAQ questions 7.27 and 7.28.
In summary, if you need to know the size of a heap-allocated array in a portable manner, you have to keep track of that size yourself.
You cannot obtain, at runtime, the size of an array if you only have a pointer to (the first element of) the array. There are no constructs at all in C that allow you to do this. You have to keep track of the length yourself.
If you happen to have an array rather than a pointer then you can find its length, but not for a pointer to an element of the array.
In your code, ptr is a pointer and so you cannot find out the length of the array to which it points. On the other hand, arr is an array and so you can find out its length with sizeof(arr)/sizeof(arr[0]).
As this other question points out, there is no portable way getting the size of a dynamic array, since malloc may allocate more memory than requested. Furthermore managing malloc requests is up to the operating system. For instance *nix would calls sbrkand store the requests somewhere. So, when you call sizeof(ptr) it returns the size of the pointer and not the size of the array. On the other hand, if your array is fixed, the size of it is determined at compile time, so the compiler is able to replace sizeof(arr) with the size of the fixed array, thus providing you the "correct" size.
The size of a pointer is 4 bytes on 32-bit machines and 8 bytes on 64-bit machines. I guess you work on a 64-bit machine since the size of an int is 4, and you got that sizeof(ptr)/sizeof(ptr[0]) is 2.
The thing to remember about sizeof is that it is a compile-time operator1; it returns the number of bytes based on the type of the operand.
The type of arr is int [24], so sizeof arr will evaluate to the number of bytes required to store 24 int values. The type of ptr is int *, so sizeof ptr will evaluate to the number of bytes required to store a single int * value. Since this happens at compile time, there's no way for sizeof to know what block of memory ptr is pointing to or how large it is.
In general, you cannot determine how large a chunk of memory a pointer points to based on the pointer value itself; that information must be tracked separately.
Stylistic nit: a preferred way to write the malloc call is
int *ptr = malloc(sizeof *ptr * N);
In C, you do not need to cast the result of malloc to the target pointer type2, and doing so can potentially mask a useful diagnostic if you forget to include stdlib.h or otherwise don't have a prototype for malloc in scope.
Secondly, notice that I pass the expression *ptr as the operand to sizeof rather than (int). This minimizes bugs in the event you change the type of ptr but forget to change the type in the corresponding malloc call. This works because sizeof doesn't attempt to evaluate the operand (meaning it doesn't attempt to dereference ptr); it only computes its type.
1 The exception to this rule occurs when sizeof is applied to a variable-length array; since the size of the array isn't determined until runtime, a sizeof operator applied to a VLA will be evaluated at runtime.
2 Note that this is not the case in C++; a cast is required, but if you're writing C++ you should be using new and delete instead of malloc and free anyway. Also, this is only true since C89; older versions of C had malloc return char * instead of void *, so for those versions the cast was required. Unless you are working on a very old implementation (such as an old VAX mini running an ancient version of VMS), this shouldn't be an issue.