realloc not changíng size of array [duplicate]
Asked Answered
C

5

5

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

Cloudland answered 10/10, 2012 at 18:31 Comment(0)
C
8

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)

Contrail answered 10/10, 2012 at 18:33 Comment(0)
P
2

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;
}
Parenthesis answered 10/10, 2012 at 18:33 Comment(0)
S
1

sizeof(parr) returns a pointer size (which is 8 bytes on your system). You need to use strlen to find out the actual character string size (note, a string should end with \0 i.e. be null-terminated).

Shy answered 10/10, 2012 at 18:34 Comment(0)
M
1

You cannot measure size of dynamically allocated array with sizeof() since it is evaluated during compilation. And in your example you are taking size of a pointer which on x64 architectures is 8B.

Maieutic answered 10/10, 2012 at 18:34 Comment(0)
S
1

It gives you the sizeof the pointer which is always the same everytime you print.

There's no way to tell the size of memory pointed by a pointer, you just have to keep track of them yourself.

As an aside, it's guranteed that sizeof(char) is always 1. So you can just remove them in your calls to realloc and malloc. You should also check the return values of malloc and realloc just to be safe.

Scleroma answered 10/10, 2012 at 18:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.