简体   繁体   中英

char* size is different than expected after malloc

I've created the next code to obtain a char* , but after executing this code the size of finalResult is bigger than expected, with some garbage characters. Why?? How can I resolve it?

//returns void
void processChar(){
            //.... more stuff here
            // init is a previous char*
            char* end = strstr(init,"</div>");
            if(end != NULL){
                    long length = strlen(init) - strlen(end);
                    if (length > 0){
                            char* finalResult = malloc(length);
                            strncat(finalResult, init,length);
                            //these lengths are different,being strlen(finalResult) > length
                            NSLog(@"%d %d",strlen(finalResult),length);
                            //... more stuff here  
                    }
            }
            return;
}

This code:

char* finalResult = malloc(length);
strncat(finalResult, init,length);

Will give you an undefined result. You're trying to concatenate finalResult with init , even though you never initialized finalResult . Perhaps you meant to use strncpy() instead of strncat() ?

Also, finalResult is not big enough; it needs to also hold the terminating \\0 character, so you should allocate it with:

char* finalResult = malloc(length + 1);

Furthermore, as pointed out by Keith Thomson, beware of the dangers of strncpy() when you're using it.

In this particular case, you can avoid using strncpy() by simply initializing finalResult as an empty string after you allocate it, and then use strncat() as you did before:

char* finalResult = malloc(length + 1);
finalResult[0] = '\0';
strncat(finalResult, init, length);

Of course you should also check the return value of malloc() for out-of-memory errors, but this is outside the scope of your question.

From man strlen:

The strlen() function calculates the length of the string s, not including the terminating '\0' character.

Obviously your malloc will need to allocate space for the terminating '\\0' character. So the fix is simple. Allocate length+1 bytes in malloc.

There is a second grave mistake in your code. Malloc will return uninitialized memory, but strncat will append to the existing string. It will therefore first search for the first '\\0' in the uninitialized memory which is not what you want. So strncat effectively depends on the first byte of whatever malloc returns being '\\0'. You want to use strncpy instead.

Code with the bugs fixed :

char * end = strstr(init, "</div>");
if (end != NULL) {
    long length = strlen(init) - strlen(end);
    if (length > 0) {
        char * finalResult = malloc(length+1);
        strncpy(finalResult, init, length);
        printf("strlen(finalResult) = %ld, length = %ld\n", strlen(finalResult), length);
        free(finalResult);
    }
}

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