473,395 Members | 1,527 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,395 software developers and data experts.

Confused by passing character arrays?

I'm still not comfortable with passing character arrays, and I think this is the problem with this code:

Expand|Select|Wrap|Line Numbers
  1. char * formatHours(int decimin)
  2. { // convert integer deci-mins (6 seconds) to string: "XXhYYm"
  3.   byte hrs, mins ;
  4.   char time[7] ;  // global scratch variable txt4 is also char [7]
  5.   hrs =  decimin / (60 * 10) ; // convert 1/10s of a minute into hours
  6.   mins = decimin % (60 * 10) ; // remainder of same division is minutes
  7.  
  8.   ByteToStr(hrs, txt4) ; 
  9.   time[0] = txt4[2] ;
  10.   time[1] = txt4[3] ;
  11.   time[2] = "h" ;
  12.  
  13.   ByteToStr(mins, txt4) ;
  14.   time[3] = txt4[2] ;
  15.   time[4] = txt4[3] ;
  16.   time[5] = "m" ;
  17.  
  18.   return time ;
  19. }

It seems to return a blank string. If I substitute the last line with return "123456" ; then that displays OK, so I guess the fault is in the above.

This formatHours() function is called within a nested call, like this:

Expand|Select|Wrap|Line Numbers
  1. strLCD5XY(formatHours(resDeciMin), 48 , 5) ; // display on LCD in small font
I have successfully used strLCD5XY() with string arguments, viz:

Expand|Select|Wrap|Line Numbers
  1. char txt4[4] ;
  2. // do something to txt4 here ...
  3. strLCD5XY(txt4, 66, 2) ;      // display on LCD in small font 
Mar 9 '10 #1
6 2911
Banfa
9,065 Expert Mod 8TB
You are returning a pointer to a local array, as soon as the function returns the array is destroyed so the pointer you return becomes invalid.

You need to return a pointer to data that has a lifetime that extends beyond the lifetime of the function call. That is either static data or data allocted on the heap. However each of these have there own problems.

For static data there is only 1 data buffer each successive call to the function over-writes the data so you can store the returned pointer for future use. Additionally in a multi-threaded environment 2 threads could try to run the function at the same time both accessing the buffer which would certainly produce the wrong results if not undefined behaviour. Any function using static data is not re-entrant.

For data allocated on the heap then the calling function has to store the returned pointer and free it when it has finished with it otherwise you get a memory leak.

The best solution (in my opinion) is for the calling function to pass a pointer to a buffer for this function to use (and may be a buffer size as well to guard against buffer overrun). You can still return the a pointer this buffer to allow you to use the function directly in a printf call. This way the calling function has complete control of the buffer used.
Mar 9 '10 #2
ISWYM about the pointer, but strangely I got it to work:

Expand|Select|Wrap|Line Numbers
  1.   ByteToStr(hrs, txt4) ;
  2.   strcat(time, txt4 +1) ;
  3.   strcat(time, "h") ;
  4. debug1 = mins ;
  5.   ByteToStr(mins, txt4) ;
  6.   strcat(time, txt4 +1) ;
  7.   strcat(time, "m") ;
  8.  
  9.   return time ;
Mar 9 '10 #3
Banfa
9,065 Expert Mod 8TB
No you did not. It only appears to work it is actually undefined behaviour.

Undefined behaviour is bad because once invoked anything can happen the behaviour of the program is completely undefined. One of the things that can happen is that the program appears to work all through testing right up until the time that it is critical that it does work and then fail. That is although it appears to work now it could stop working at any time in the future for no apparent reason.
Mar 10 '10 #4
What I meant was that I got the function to do what I expected, now I need to consider the undefined behavior.

I have changed my return statement to:

return (strcpy(txt7, time)) ;

where txt7 is a global scratch variable. Is this OK?
Mar 10 '10 #5
Banfa
9,065 Expert Mod 8TB
Well that will work as long as you understand the limitations of using a static data buffer as I outlined in post #2.

Also generally speaking global data is bad practice so you should give your global scratch variable the smallest scope possible. What that actually means is declaring it static inside the function like this

Expand|Select|Wrap|Line Numbers
  1. char * formatHours(int decimin)
  2. { // convert integer deci-mins (6 seconds) to string: "XXhYYm"
  3.   static char txt7[7];
  4.  
  5. <Code Snipped> 
  6.   return (strcpy(txt7, time)) ;
  7. }
  8.  
This limits the scope of txt7 to the formatHours function ensuring no-one else can mess with it directly.
Mar 10 '10 #6
donbock
2,426 Expert 2GB
What's the advantage of building the string in the time array and then copying it to the txt7 array compared with building the string in the txt7 array in the first place?
Mar 10 '10 #7

Sign in to post your reply or Sign up for a free account.

Similar topics

58
by: jr | last post by:
Sorry for this very dumb question, but I've clearly got a long way to go! Can someone please help me pass an array into a function. Here's a starting point. void TheMainFunc() { // Body of...
8
by: kalinga1234 | last post by:
there is a problem regarding passing array of characters to another function(without using structures,pointer etc,).can anybody help me to solve the problem.
10
by: Pete | last post by:
Can someone please help, I'm trying to pass an array to a function, do some operation on that array, then return it for further use. The errors I am getting for the following code are, differences...
15
by: Carramba | last post by:
hi! I am trying to confirm if input is digit, so I thought it would by easy to do it with with isdigit() funktion, but how do I pass arrays to it if the imput is more then 1 sign? #include...
3
by: linguae | last post by:
Hello. In my C program, I have an array of character pointers. I'm trying to input character strings to each index of the character pointer array using scanf(), but when I run the program, I get...
3
by: Mark | last post by:
Hi From what I understand, you can pass arrays from classic ASP to .NET using interop, but you have to change the type of the.NET parameter to object. This seems to be because classic ASP passes...
15
by: rEvolution27 | last post by:
I'm a c++ newbie here, trying out some stuff and when I try to compile this: void create() { char name; cout << "Creating a new timetable /n Please type a name for this timetable"; cin >name;...
2
by: luis | last post by:
I'm using ctypes to call a fortran dll from python. I have no problems passing integer and double arryas, but I have an error with str arrys. For example: ..... StringVector = c_char_p *...
3
by: Tarik Monem | last post by:
Hi Everyone, Still a newbie with FLEX, and I've passed arrays using AJAX to FLEX before, but I've never passed links to FLEX. Basically, this is the OUTPUT, which I wanted, but I'm given an...
8
by: S. | last post by:
Hi all, Can someone please help me with this? I have the following struct: typedef struct { char *name; int age; } Student;
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.