简体   繁体   中英

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.

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.

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.

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.

sizeof(s)返回char *s的大小,即4(32位)或8(64位)系统。

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.)

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.

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:

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM