?
Solved

when using declaring type char for my function, does the returned value follow the type as well?

Posted on 2003-03-18
4
Medium Priority
?
221 Views
Last Modified: 2010-08-05
This is the function I'm using

char BINTOC(int genes1)
{
     char bin_str[BINSIZE];
     
     _itoa(genes1, bin_str, 2);

     return(bin_str[BINSIZE]);

}

Does the function return a char type or a char[] type?

Thks
0
Comment
Question by:e_chaos
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
4 Comments
 
LVL 15

Accepted Solution

by:
efn earned 80 total points
ID: 8164328
You declared it to return a char, so it's going to return a char.

The expression bin_str[BINSIZE] outside of a declaration does not refer to the whole array.  It refers to the character just past the end of array, since the elements of the array are bin_str[0] through bin_str[BINSIZE - 1].

In general, the compiler will insist that a function return what it is declared to return.
0
 
LVL 30

Expert Comment

by:Mayank S
ID: 8164509
Of course it is supposed to return a char[] type only, but here, the character that you're returning is outside the range of the array. The range of the bin_str[] array is 0 to BINSIZE - 1.

However, in this case, it will return any garbage character which will be the character-equivalent of the byte (or 2 bytes - depending upon storage of a 'char' type) stored at the location ahead of bin_str[BINSIZE - 1].

Mayank.
0
 
LVL 12

Assisted Solution

by:Salte
Salte earned 80 total points
ID: 8166034
In general it is a bad idea to do:

char * BINTOC(int genes1)
{
   char bin_str[BINSIZE];
   _ltoa(genes1,bin_str,2);
   return bin_str;
}

Even though this is better than your original code.

1. The return type is char * so you can return an array and not just a single char. In this case you want to return an array that hold a string, so returning a pointer is what you want.

C and C++ has no array return type, you can't write:

char [] BINTOC()
{
}


2. The return is bin_str which is a pointer to the first char of that array, bin_str + 1 etc give pointers to the next characters of the string.

However, one major flaw with the function is that when the function returns the array that was declared on the stack also vanish along with any other local variables.

To correct for this error you can do any of the following:

a. Use a global array to stuff the result. Problem here is that other functions might mess with the string, but if you can handle that this is an ok solution. One major flaw is that you can't call the function twice in a row since the second call will overwrite the first:

printf( "result is a = %s and b = %s\n",
    BINTOC(3), BINTOC(5));

Will print "result is a = 5 and b = 5\n" or "result is a = 3 and b = 3\n". In neither case will it display "result is a = 3 and b = 5\n" as you wanted.

char bin_str[BINSIZE];

char * BINTOC(int genes1)
{
   _ltoa(genes1,bin_str,2);
   return bin_str;
}

b. Declare the array static in the function. This keeps it off the stack but has the same flaw as method a if you want to call it several times in a row.

char * BINTOC(int genes1)
{
   static char bin_str[BINSIZE];
   _ltoa(genes1,bin_str,2);
   return bin_str;
}

c. allocate the array on heap. This also keeps it off the stack but you have a problem that caller must remember to deallocate the string when it is no longer needed.

char * BINTOC(int genes1)
{
   char * bin_str = new char[BINSIZE];
   _ltoa(genes1,bin_str,2);
   return bin_str;
}

This time if you call it in that printf shown earlier you will call it and printf will use the string but since nobody delete [] the string after it is used you will have memory leaks, the proper way to use the function in this case is therefore:

void do_something()
{
   char * s = BINTOC(3);
   // use the string. s is the string "11" now.

   // then when you are done with the string, you must:
   delete [] s;
}

d. Don't use char at all but use std::string
This removes all the problems from earlier, the string class allcoates the actual buffer of the string on heap but the string class itself handles deallocation of that buffer so you don't have to worry about it.

std::string BINTOC(int genes1)
{
   char bin_str[BINSIZE];
   _ltoa(genes1,bin_str,2);
   return std::string(bin_str);
}

Here the char buffer is allocated on stack as in the original function but it is copied to a string object before we return and it is that string object we return so even though the bin_str goes bye bye when the function returns the string object still holds its copy of the string.

I will recommend you use std::string for your program. One problem is that it cannot be used easily with printf since printf doesn't take class arguments easily. However, you can do it in either of the following ways:

i) use cout:  cout << "a = " << BINTOC(3) << endl;

ii) use printf() but convert the string object to const char * before given as argument to printf.

printf( "a = %s, b = %s\n", BINTOC(3).c_str(), (const char *)BINTOC(5));

Here I have shown both ways of getting a const char * from a std::string object. Unlike the previous printf() with two BINTOC calls this one WILL print out the numbers the way you expect:

"a = 11, b = 101\n"

The string objects will be destroyed after printf() returns and then the strings will be deallocated so you don't have to worry about the strings either.

Hope this is of help.

Alf
0
 
LVL 9

Expert Comment

by:tinchos
ID: 9510522
No comment has been added lately, so it's time to clean up this TA.
I will leave a recommendation in the Cleanup topic area that this question is:

Split points between efn & Salte

Please leave any comments here within the next seven days.

PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!

Tinchos
EE Cleanup Volunteer
0

Featured Post

On Demand Webinar: Networking for the Cloud Era

Ready to improve network connectivity? Watch this webinar to learn how SD-WANs and a one-click instant connect tool can boost provisions, deployment, and management of your cloud connection.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Often, when implementing a feature, you won't know how certain events should be handled at the point where they occur and you'd rather defer to the user of your function or class. For example, a XML parser will extract a tag from the source code, wh…
Many modern programming languages support the concept of a property -- a class member that combines characteristics of both a data member and a method.  These are sometimes called "smart fields" because you can add logic that is applied automaticall…
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.
Suggested Courses

765 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question