Hi,

I have a doubt, in the following program, it prints the string returned by throwstring()function.

Is the string which the function is returning is local to the function or outside of the function?

Can somebody throw light on underlying mechanism..

main()
   {
      char* throwstring();
      printf("%s\n", throwstring());
    }
    
    char *throwstring()
     {
       return "I'm from throwstring func";
     }

Thanks in Advance

Recommended Answers

All 12 Replies

Its ok because string literals are in the heap and not the stack. However, because the function is returning a string literal the return value should be declared as const keyword.

const char *throwstring();

main() should be declared as int main() and not leave it up to the compiler to fill in the blanks.

Function prototypes (see line 3 of your post) normally appear outside any function. So you should move line 3 up above line 1.

Thank you much for your reply..

One more question, if this string is in Heap. Who will take care to free this memory.

Regards

The os will take care of it when the program terminates. You don't have to mess with freeing memory for string literals. All you are concerned with is call free() to release memory allocated by malloc(), calloc(), realloc(), or pointers returned by functions that allocate memory by one of those functions. If you are writing MS-Windows programs then there are additional requirements, but don't worry about those either for now.

What happenes, the function throwstring() return the pointer to the first elements of the string const - which is located in heap- to the main. And printf use the base address to print of the full string till it hits NULL.

And as mentioned before. You should specify the int before main. By defualt compiler will assume that main return an int. But it is a good idea to specify. And a reture value to return 0;

const char *throwstring()
{
   return "I'm from throwstring func";
}
int main()
{
    char* throwstring();
    printf("%s\n", throwstring());
    
    return 0
}

ssharish

>By defualt compiler will assume that main return an int.
Only prior to C99. In C99, omitting the return type is a syntax error.

>Its ok because string literals are in the heap and not the stack.
The who and the what? It's easy to write an implementation that places string literals on the stack, or anywhere else as long as they behave as if they have static storage duration. Saying that they're on the heap is misleading at best, especially since you can write a test on many compilers that proves the size of a string literal affects the size of the executable file (assuming, as everyone does, that "heap" means the same pool of dynamic memory given by malloc).

I am kind of confuse now.
I always thought a literal string was static and constant. Which made me believe that it would be part of the static memory, like a global static variable. And that it would be undefined behaviour if you tried to change it by using a pointer.
Am I wrong thinking like this?.

>Am I wrong thinking like this?.
No, but you're not entirely right either. A string literal is potentially stored in read-only or shared memory, and it's required to have static storage duration. If those rules are met, the compiler is free to put string literals wherever it likes.

Yes, Narue is correct. I misspoke when I said string literals are on the heap. The compilers I have used always places them in global static read-only memory, but string literals could also be placed elsewhere by other compilers.

Hi Narue,

It looks like if the string is created as

char buff1[] = "string storage";

is created in stack. where as string created as
char *buff2 ="string storage";

is created in global memory. is it true?? can you please confirm it.

if we just return string as in throwsting() function

char *throwstring()
{
return "I'm from throwstring func";
}

looks it is created in global memory.

Just I want another confirmation. That is if we are running a demon and we call this throwstring() function manytimes in that then this may result in a memory overflow, right?

Thanks in Adance.

It looks like if the string is created as

char buff1[] = "string storage";

is created in stack. where as string created as
char *buff2 ="string storage";

is created in global memory. is it true?? can you please confirm it.

The string literal will be treated the same in both cases, however, what you do with it changes. In the first line, you're copying the contents of the string literal into your own array that's likely stored on the stack, such as in this case:

int main ( void )
{
  char buff1[] = "string storage";
  return 0;
}

"string message" is stored where all string literals are, but its contents are copied into buff1 is which stored on the "stack"[1] as a local variable. Your second line doesn't store the contents of the string literal, it creates a pointer that points to that memory. The pointer is likely on the stack, but the memory it points to is wherever the implementation placed it. A more precise example:

int main ( void )
{
  char *buff2 = "string message";
  return 0;
}

"string message" is stored where all string literals are, and its address is copied into buff2, which is stored on the stack as a local variable.

>That is if we are running a demon and we call this throwstring() function manytimes in that
>then this may result in a memory overflow, right?
No, I don't see that happening. Even if your implementation doesn't stored string literals in shared memory (that is, literals with the same contents refer to the same location in memory), you're only dealing with one, so the address of that one will always be returned from the function in any decent compiler. Any allocation will occur once and that memory will be reused for the life of the program.

What you're doing is confusing the memory for an actual string literal with the memory for an array or a pointer. Put simply, you don't have to worry about the memory for anything wrapped in double quotes. When you save a pointer to a string literal, you have to take care not to modify the contents:

int main ( void )
{
  char *buff2 = "string message";

  buff2[6] = '-'; /* Don't do this! */

  return 0;
}

Which you can more or less guarantee by making the pointer a pointer to const:

int main ( void )
{
  const char *buff2 = "string message";

  buff2[6] = '-'; /* Now it won't compile */

  return 0;
}

If you copy the contents of a string literal into an array, then you can start worrying about storage costs, but only when it comes to your array, not the string literal. For example:

int main ( void )
{
  char buff1[] = "string storage";
  return 0;
}

You need to take into consideration the storage for buff1, but the storage for "string storage" is beyond your control and none of your business.

[1] Of course, "stack" doesn't refer to a stack proper, but the way in which local variables are required to behave. This is called the "as if" rule, which says that local variables and function calls are required to behave as if they're being pushed and popped using a stack at execution time.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.