ksb
ksb

Reputation: 710

malloc(sizeof(s)) allocates less memory than expected?

hey i am having problems using the sizeof operator in malloc. For example see the foll. code-

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
char * copy(char *s)
{
    char *t=malloc(sizeof(s));
    char *ptr=s;
    int i=0;
    do
    {
        t[i++]=*ptr++;
    }
    while(*ptr!='\0');
    return t;
}
int main()
{
    char *s="hello adsjahsjkdhjkashdkjaskdasldjlasjdlajsdlkjaslkdjalsjdlasjdljasdljasdkljklsdjlasdsadasdasd";
    char *b=copy(s);
    printf("%s\n",b);
    free(b);
    return 0;
}

on ideone, it gives the error:- * glibc detected ./prog: free(): invalid next size (fast): 0x09bcf008 **

But when i replace malloc(sizeof(s)) with malloc(strlen(s)+1) , the program works perfectly. So whats the problem? NOTE:this is just a small prog i created to demonstrate the problem i was having in another code.

Upvotes: 2

Views: 3609

Answers (7)

fatima
fatima

Reputation: 1

malloc is declared in , so we #include that header in any program that calls malloc. A ``byte'' in C is, by definition, an amount of storage suitable for storing one character, so the above invocation of malloc gives us exactly as many chars as we ask for. We could illustrate the resulting pointer like this:

Upvotes: 0

Cacho Santa
Cacho Santa

Reputation: 6914

You should use strlen instead of sizeof in the copy function:

char * copy(char *s)
{
    char *t=malloc(strlen(s) + 1);
    char *ptr=s;
    int i=0;
    do
    {
        t[i++]=*ptr++;
    }
    while(*ptr!='\0');
    return t;
}

The problem is that sizeof does not return the value you need, that function will return the size of the char *s (probably 4 or 8 -> bytes used to storage that pointer). Check the documentation links to understand more clearly.

One more thing, if you are doing that in order to practice your C skills is OK but if you are not, you will probable just want to use the strcpy function.

Hope it helps.

Upvotes: 6

Abhijit
Abhijit

Reputation: 63707

arrays and strings with size information gets degenerated to pointers losing its size attributes when it is passed as a parameter to a function

So when you are calculating the size of the parameter s it either returns 32/64 based on your bitness.

instead of sizeof, you should actually do strlen and add one to it to accommodate the null character.

instead of

char *t=malloc(sizeof(s));

try

char *t=malloc(strlen(s)+1);

Please note:

There are other design issues with your code

  1. When passing a pointer argument which is not supposed to change, you should declare it const.

  2. Generally returning an address of a locally generated heap storage is not a good practice and is the major cause of memory leak, if cal-lee ever forgets to free the storage. Instead pass it as a non-const parameter to the function.

Upvotes: 4

Jerry Coffin
Jerry Coffin

Reputation: 490048

s is a pointer to char, so malloc(sizeof(s)) allocates space for one pointer to char -- typically 2-8 bytes, most often 4 bytes. As it stands, it'll always allocate this fixed amount of space, regardless of the length of string you passed in. In your test, you're passing a much longer string than that, so you overflow the buffer you allocated.

You're already given the correct answer: under the circumstances, strlen is the right function to find the size.

Upvotes: 1

geekosaur
geekosaur

Reputation: 61369

sizeof returns the size of the pointer (usually 4 or 8 bytes), not the size of the pointed-to object. (There is no way to get at the latter information. sizeof is effectively a compile-time constant, by the way.)

Upvotes: 1

Daniel Roethlisberger
Daniel Roethlisberger

Reputation: 7058

sizeof(s) returns the size of char *s which is 4 (on 32 bit) or 8 (on 64 bit) systems.

Upvotes: 4

cnicutar
cnicutar

Reputation: 182619

The operator sizeof doesn't do what you want on pointers. It yields the size of the pointer on your machine (which will be something like 4 or 8).

You can think of it this way: the array decays to a pointer when passed to a function and the information regarding its size is "lost".


Also note your loop doesn't fill in the 0 terminator.

Upvotes: 6

Related Questions