Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

realloc not changíng size of array [duplicate]

Tags:

arrays

c

realloc

Possible Duplicate:
Realloc is not resizing array of pointers

Can anyone tell me where my mistake is? this function should make an array of the characters supplied from stdin. I read some related questions but it was too complicated for me to understand.

char *readChar(void)
{
    int c;
    int len = 0;
    char* parr = malloc(sizeof(char));

    while((c = getchar()) != EOF)
    {
        ++len;
        int size = sizeof(char)*len;
        parr = (char *) realloc(parr,size);
        *(parr+size-1) = (char) c;
        printf("Done! Size should be: %dB, but real size is %dB\n",size,sizeof(parr));
    }

    return parr;
}

Output:

Done! Size should be: 1B, but real size is 8B Done! Size should be: 2B, but real size is 8B Done! Size should be: 3B, but real size is 8B Done! Size should be: 4B, but real size is 8B

like image 737
Lukasik Avatar asked Oct 10 '12 18:10

Lukasik


2 Answers

The mistake is that sizeof() won't tell you the number of bytes you allocated. It tells you the size of the char *

Sounds like what you wanted was to verify that you allocated the correct amount of memory. sizeof() won't give you that information. It's in the low level details at this point, you need to do something OS dependent to try and find that information. (ex. in the Linux kernel if you kmalloc() memory you can use ksize() to find out exactly how many bytes you got)

like image 88
Mike Avatar answered Sep 19 '22 03:09

Mike


sizeof(parr) is NOT the amount of allocated space, it is the size of char* (parr's datatype). The only portable way to know the amount of memory you have allocated is to keep track of it yourself.

Assuming that realloc is working as expected, the amount of bytes you have allocated will be equal to your variable size.

Just a few other things I noticed in your code:

    char* parr = malloc(sizeof(char));

You should always check the return value of malloc to ensure that it succeeded:

 char* parr;
 if(!(par = malloc(sizeof(char)))
 {
     //allocation failed
 }

The next part of your code that caught my eye:

 int size = sizeof(char)*len;

This is actually not needed. sizeof(char) is always equal to one byte, so you might as well just use the current value of len instead of declaring a new variable which is equal to len * 1 on each iteration of your loop.

  parr = (char *) realloc(parr,size);

As mentioned earlier you don't need to use size since it is equivelent to len. Also in C it is generally not a good idea to cast your pointers, you should also check the return value of realloc incase it fails:

if(!(parr = realloc(parr, size)))
{
    //allocation failed
}

As a last note I always use a buffer when using the realloc function to avoid potential memory issues. Here is my spin on your code:

char *readChar(void)
{
    int c, len = 0;
    char* parr = NULL, char *tmp;

    if(!(parr = malloc(sizeof(char)))
    {
        fputs("memory allocation failed", stderr);
        exit(1);
    }

    while((c = getchar()) != EOF)
    {
        ++len;
        if(!(tmp = realloc(parr, len)))
        {
            free(parr);
            fputs("memory allocation failed", stderr);
            exit(1);
        }
        parr = tmp;
        *(parr+len-1) = (char) c;
    }
    return parr;
}
like image 40
Keith Miller Avatar answered Sep 19 '22 03:09

Keith Miller