0

I am trying to return a string from str function but it prints (null)

#include<stdio.h>
char* str()
{
    char hi[10] = "return this";
    return hi;
}

void main()
{
    printf("%s", str());

}
Ashraful
  • 19
  • 5
  • Since _hi_ is within the scope of _str_, it's doesn't make sense to return it's address out of the scope. – mbaitoff Nov 15 '20 at 17:10

4 Answers4

1

In GCC at least your code compiles with teh following warnings:

main.c:12:19: warning: initializer-string for array of chars is too long                                                                        
main.c:13:12: warning: function returns address of local variable [-Wreturn-local-addr]  

Which more or less is a direct answer to your question. If you did not get these warnings, consider the compiler switched you are using, for GCC I suggest at least -Wall -Werror - that will output the most useful warnings without being pedantic, and make those warnings errors so will prevent successful compilation until you fix them.

You are returning a pointer to a local-automatic variable that is no longer in scope after the function returns, so the result is undefined. You have also tried to initialise an array with more characters that you have reserved.

What the compiler has done here is given the invalid initialiser, it has set the address of hi to null, and printf has handles the null pointer by printing (null). That is behaviour specific to your compiler and C library - in other cases something different may happen. More insidious that that is that if your initialiser was not invalid (by being shorter), it is likely to have appeared to work and you might never have asked the question, but it would still be incorrect, and in more complex code would likely at some point cause observable erroneous behaviour.

In this particular case you could do any of the following:

const char* str()
{
    static const char* hi = "return this";
    return hi;
}
const char* str()
{
    static const char hi[] = "return this";
    return hi;
}
char* str( char* str, int maxlen )
{
    str[maxlen] = '\0' ;
    return strncpy( str, "return this", maxlen - 1 ) ;
}

void main()
{
    char* buffer[32] ;
    printf("%s", str(buffer, sizeof(buffer));
}

The most appropriate solution (and the above are by no means exhaustive) depend on what you actually want to do, since each solution differs semantically, and on its own this function is hardly practical. It would need a concrete real-world example to give best advice.

Clifford
  • 88,407
  • 13
  • 85
  • 165
1

read static variables or global variables to access the variable outside the functions

there is an overflow in your code, read buffer overflow in c

Also read What should main() return in C and C++?

#include<stdio.h>
char* str()
{
    static char hi[] = "return this";
    return hi;
}

int main()
{
    printf("%s", str());
    return 0;
}
csavvy
  • 761
  • 4
  • 13
  • The initialiser being too large does not cause a overflow because it is checked at compile time, which is why it prints `(null)` - though it is still undefined behaviour. If you shorten the initialiser it may (and in this simple case is likely to) _appear_ to work, but it is still wrong. – Clifford Nov 15 '20 at 17:55
  • not sure of that, but it is still not the correct way of doing it, right? – csavvy Nov 15 '20 at 18:16
  • That is right. The behaviour I described I determined empirically at gdbonline (GCC).. YMMV. A poorly implemented compiler could well overflow the buffer. – Clifford Nov 15 '20 at 18:44
1

The problem is with the scope of the character array.

The solution for this issue is to make the address of that variable visible to the caller function!

i.e. one of the easiest solutions is use the below line in the declaration part of hi variable in your str() function. i.e. static char hi[10] = "return th";

in the declaration. This way you wouldn't need to change anything in this program BUT in the whole program, this variable WILL BE visible/accessible throughout the execution.

#include"stdio.h"

char* str() {
    static char hi[10] = "return th";
    return hi; 
}

int main() {
    printf("%s", str());
    return 0;
}
Samarth
  • 130
  • 5
  • In what manner does your solution make the variable _"visible/accessible"_ throughout the whole project? A variable has _scope_ and _lifetime_, by declaring a local `static` it has a _lifetime_ of the duration of the program, but it is no more visible that a non-static variable because it has the _same scope_. – Clifford Nov 15 '20 at 17:48
  • You should edit the answer to add explanatory code, not add it in comments. Comments are not part of the answer and are certainly not suited to posting code. – Clifford Nov 15 '20 at 17:49
-2
#include<stdio.h>
#include<stdlib.h>
char* str(){
    //malloc is used to allocate memory
    char *hi=(char*)malloc(sizeof(char)*20);
    char ch[]="return this\0";
    for(int i=0;i<sizeof(ch);i++)
    hi[i]=ch[i];
    return hi;
} 
int main(){
    printf("%s", str());
    return 0;
}

you can find more about malloc and sizeof operator.

Udesh
  • 2,415
  • 2
  • 22
  • 32
  • Your hi variable scope was limited to `str function` .so when execution comes out of str function the stack is cleared and so the memory allocated for hi is also cleared due to that it was giving segmentation fault. – Udesh Nov 15 '20 at 17:23
  • Yuk. Just swapping one problem for another ( a memory leak). Also `sizeof(char)` is 1 by definition, so `sizeof(char)*20` has no benefit over just `20` here. – Clifford Nov 15 '20 at 17:40
  • 1
    Your comment to your own answer is part of the answer and should appear in the answer. Just throwing code out with no explanation is not really an answer to the question, even if it is a solution to the problem. – Clifford Nov 15 '20 at 17:43