0

In this example i want to learn how to dynamically allocate the memory. This is my code:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main()
{
   int n = 0;
   char a[]="asd";

   n = sizeof(a)/sizeof(char);
   printf("\n %i \n\n",n);

   char *corner;

   corner = (char *)malloc(sizeof(char)*n);

   strcpy(corner, a);

   printf("\n %s \n\n",corner);

   free(corner);

   char b[]="asdddddddd";

   n = sizeof(b)/sizeof(char);

   corner = (char *)malloc(sizeof(char)*n);

   strcpy(corner, b);

   printf("\n %s \n\n",corner);

   int x = sizeof(corner)/sizeof(corner[0]);

   printf("\n %i \n\n",x);

   return 0;
}

The result of this code is :

 4 


 asd 


 asdddddddd 


 4 

So I dont know how to use malloc and free properly. First part of code is clear for me. First i am measuring lenght of array a, then i am creating pointer to the same lenght of memory as array a uses, next i am copying array a to another place in memory pointed by *corner.

After printing string of characters I want to reuse corner, so i am freeing the memory and try to define the new lenght of array because i want to store other (longer or shorter) string. I dont know why, "new" corner is printing properly but when i am checking it lenght it shows me 4 again. Why? Is corner only 4 chars long? How to recreate corner with proper lenght? I know that this part of code makes no sense but this is only for traning.

R Sahu
  • 204,454
  • 14
  • 159
  • 270
susi33
  • 207
  • 1
  • 2
  • 4
  • Yes, "sizeof(char)" is 1, by definition, so is just wasted typing. But you have other problems: first of all you need to allocate n+1 bytes to make room for the null byte. Second, sizeof(corner) is just the size of a pointer, probably 4 or 8 bytes--C doesn't know how many bytes are being used there, you need strlen() for that. – Lee Daniel Crocker May 05 '15 at 17:51
  • To summarize what is said in the answers, you compare the size of an array of chars (`a`) with the size of a pointer (`corner`) and, by chance, it happens that on your system both of them are `4`. The size of the array you are talking about in the title is also stored in `n`, not in `x`, and it changes (print it to see). – axiac May 05 '15 at 17:55
  • @LeeDanielCrocker: Why 'n+1'? In first case i have 3 letters '"asd"' but the 'n = 4', so when i am allocating memory i allocate corner[0] for a, corner[1] for s, corner[2] for d, and corner[3] for /0. Am I right? – susi33 May 05 '15 at 18:15
  • You're right, `sizeof("abc")` is `4`, and that's fine. The standard idiom for allocating space for strings, though, is `malloc(strlen(s)+1)`, because `strlen()` does not count the terminator. – Lee Daniel Crocker May 05 '15 at 18:20
  • @LeeDanielCrocker: But why if I reserve for example memory for 5 chars by malloc (for example "apple") I can using same pointer type "i hate eating apples" and is no problem for compiler? `char b[]="asdddddddd";` `n = sizeof(b)/sizeof(char);` `corner = (char *)malloc(sizeof(char)*n);` `corner = "adadasdsadadsdaddsddasdasdsaddssdf";` This code is compiling with no problem. Why? – susi33 May 05 '15 at 18:24
  • The compiler doesn't know what you're going to do at runtime. If you tell it to allocate 4 bytes, then copy 100 bytes to that address, it's quite happy to let you shoot yourself in the foot. C is a low-level language--it requires you to do for yourself what higher-level languages do for you, like memory management. – Lee Daniel Crocker May 05 '15 at 18:34
  • Don't cast `malloc` in C. – crashmstr May 05 '15 at 18:56

6 Answers6

3
int x = sizeof(corner)/sizeof(corner[0]);

sizeof(corner) gives you sizeof(pointer) not sizeof(array) as you expect, it looks like sizeof(pointer) = 4 bytes in your system.

Please note that your strings should be \0 terminated and you should allocate memory for the nul character also which you are not doing and it will lead to undefined behavior.

Gopi
  • 19,784
  • 4
  • 24
  • 36
  • So how i can measure lenght of this chunk of memory pointed by 'corner' ? – susi33 May 05 '15 at 17:52
  • @susi33 While allocating memory you know the size right? `n` so it has to be the size of the array isn't it ? – Gopi May 05 '15 at 17:53
  • It wasnt so obvious for me because i dont know how to use malloc and i wanted to try this out :) Earlier i was trying to simple "overwrite" my strings but that was disaster :D – susi33 May 05 '15 at 18:01
  • @susi33 ok now you got what went wrong in your code right? – Gopi May 05 '15 at 18:14
0

In your code, corner is a char pointer and its size is ... the size of a char pointer, whether it points to NULL, a char array of any size, or nowhere in memory ! That's the reason why its size is always 4 on a 32 bits system.

Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252
0

You fetching the size of memory which you just created not the size of array so,There is no way to know the size of a dynamically allocated array , It depends on the architecture of your computer whether it is of 32 bits or 64 bits , 4 bytes is for 32bits system while 8 bytes for a 64bits system.

Farrukh Faizy
  • 1,203
  • 2
  • 18
  • 30
0

First i am measuring lenght of array a, then i am creating pointer to the same lenght of memory as array a uses, next i am copying array a to another place in memory pointed by *corner.

In the both cases you are using sizeof( corner )

int x = sizeof(corner)/sizeof(corner[0]);

where corner has type char *

char *corner;

Thus sizeof( corner ) is equivalent to sizeof( char * ) and does not depend on how much memory was allocated pointed to by the pointer.

Pointers do not keep information about whether they point to a single object or the first object of an array of some size.

So shortly answering your question

Why array size is not changing?

It is the pointer size that is not changing.:)

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
0

In C, it's not possible to identify the size of the array pointed to by a malloced address by having only the return pointer. You need to manually maintain a data structure to handle this type of issue. Otherwise, you would only be able to get the sizeof the pointer itself and nothing more.

Jerry Ajay
  • 1,084
  • 11
  • 26
0

As someone already wrote here sizeof(corner) is whatever size your memory word is - 8 on 64 bits processors if you compile on 64 bits,4 on your system since very likely you have a linux on 32 bits and than you compiled on 32 bits. Or you have a 64 bits linux and you do not have 64 bits compilation enabled by default , you compiled for 32 bits.

To compile on 32 or on 64 bits you use the flags -m32 or -m64 for gcc.

As for your question,usually there is not possible to know how much memory a pointer got allocated.

However,on linux there is a function that does that: Is it possible to find the Memory Allocated to the Pointer, without searching for the malloc statement

Just do a man malloc_usable_size

However,I do not think the function is guaranteed to work.

I managed to use the function,but lowest dimension that it returns for a pointer is 24 octets.

I have 64 bits linux and the program is compiled on 64 bits.

If I allocate 25 octets,than I get 40 returned.

If I allocate 100 octets than I get 100 returned by the function.

Community
  • 1
  • 1