0
#include<stdio.h>
#include<string.h>
#include<stdlib.h>

char *func(char * str){


    int len;
    len=strlen(str)+3;
    str = (char *)realloc(str,len);
    return str;


}

void main(){

    printf("str:%s",func("hello"));

}

The final ans prints (null),instead of printing the string: "hello". Can anyone please explain why is it so? I am unable to identify any error. Can anyone rectify the error, and help me with a working code. Please!

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
Anonymous
  • 145
  • 1
  • 1
  • 12
  • 1
    `void main(){..` No wonder.... – Sourav Ghosh Jul 04 '16 at 15:04
  • 3
    You call realloc on a char * that can't be realloced. So it fails, and returns NULL. – William Pursell Jul 04 '16 at 15:05
  • The question is tagged `dynamic-allocation`, and yet there's none in sight... @WilliamPursell Shouldn't this generate a warning, or complete failure to compile, for passing a `char const *` (type of string literal) to `func()`? I mostly program C++14 with all warnings on, so maybe I'm too used to good type safety... – underscore_d Jul 04 '16 at 15:06
  • 1
    @underscore_d String literal is of type `char*`. – 2501 Jul 04 '16 at 15:11
  • @2501 Then I guess that's a C thing. More's the pity. In C++, implicitly converting `char const *` to `char *` is still legal but deprecated, and many compilers will warn the programmer into oblivion for trying it: http://stackoverflow.com/a/2760547/2757035 And rightly so! Any attempt to edit that [scare quotes] '`char *`' is UB, and too easy to try. – underscore_d Jul 04 '16 at 15:13
  • 1
    __Can anyone rectify the error, and help me with a working code. Please!__ Sorry, did you actually take ypour time to read the given answers? We're not here to write the code for you, we can only show you the way... – Sourav Ghosh Jul 04 '16 at 15:13
  • @underscore_d I don't get your point. You can't convert const to non-const in C without a cast either. – 2501 Jul 04 '16 at 15:15
  • @2501 My point is that C++ is stricter and defines string literals as `char const *`, whereas C just uses `char *`. C++ is seemingly also dropping the ability to silently convert and drop the const. – underscore_d Jul 04 '16 at 15:23
  • @underscore_d `C++ is seemingly also dropping the ability to silently convert and drop the const` There is no such feature in C. You can't convert const to non-const in C without a cast. – 2501 Jul 04 '16 at 15:25
  • 1
    @2501 Please read again and let me know if I've misunderstood. In C, string literals are not `const`. In C++, they are `const` _but_ could be implicitly converted in contexts such as this. In C++, this is now strongly deprecated or even forbidden, depending on which compiler you ask. – underscore_d Jul 04 '16 at 15:28
  • 4
    [Don't cast the result of `malloc` in C](http://stackoverflow.com/q/605845/995714) – phuclv Jul 04 '16 at 15:32

3 Answers3

6

Your program invokes undefined behavior because you're passing a pointer, which was not previously returned by dynamic memory allocator family of functions, to realloc().

According to C11, chapter §7.22.3.5, The realloc function, (emphasis mine)

If ptr is a null pointer, the realloc function behaves like the malloc function for the specified size. Otherwise, if ptr does not match a pointer earlier returned by a memory management function, or if the space has been deallocated by a call to the free or realloc function, the behavior is undefined. [...]

That said,

Community
  • 1
  • 1
Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
6

"hello" is a read-only string literal. Its type is really a const char* although compilers allow assignment to a char* despite all the merry hell that this causes.

The behaviour on calling realloc on such a pointer is undefined. So the compiler can do anything it likes. It might eat your cat.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
1

You may realloc an object that was allocated dynamically. String literals have static storage duration and may not be changed. Any attempt to modify a string literal results in undefined behavior.

What you could do is the following

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char *func( const char * str )
{
    size_t len = strlen( str ) + 3;

    char *tmp = realloc( NULL, len );

    if ( tmp ) strcpy( tmp, str );

    return tmp;
}

int main( void )
{
    char *str = func( "hello" );

    if ( str ) printf( "str: %s\n", str );

    free( str );
}

The program output is

str: hello

Take into account that the call

realloc( NULL, len )

is equivalent to

malloc( len )
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335