Go Down

Topic: Quick pointer question.. (Read 6 times) previous topic - next topic

timmaah

Feb 03, 2008, 04:31 pm Last Edit: Feb 03, 2008, 04:32 pm by timmaah Reason: 1
Say I have a bunch of text stored like:

char *disp[] = {"AAAA","BBBB","CCCC","DDDD"};

And at some point I need to change one of those strings..

disp[0] = inString;

That works.. but its only updating the pointer to now point to inString, thus any time inString is changed disp[0] is "changed"

I thought

*disp[0] = inString;

would work but gives an "invalid conversion from 'char*' to 'char'" error..

How do I go about updating the string that the pointer disp[0] is pointing to? I have googled all over and can't seem to find any code that matches what I am doing.. so if there is another way to do this, I'm open to that as well.

Thanks...

-timw

kg4wsv

You are really allocating a 2D array.  A "string" in c isn't a real data type, it is a special case of an array of characters.  In your code, disp is an array of pointers, and that array of pointers are of the type character array.  Or, you can think of it as a 2D array of characters.  Arrays in C are wonderfully (dangerously?) flexible things.

You can't assign an array in one fell swoop with the "=" operator*.  C doesn't do that. Even arrays that don't look like arrays because C is pretending to support strings.  That's why there are functions like strcpy() in the standard C library (but probably not in Arduino's library, due to microcontroller size constraints).

If inString is an array of characters, then al you are doing is assigning the first element of disp to point to the same place that inString points to, hence the behavior you see.  Incidentally, this also loses the reference to the original array pointed to by disp[0], resulting in a memory leak.

What you basically have to do is copy the contents of inString to disp[0], one character at a time, checking to make sure that you stop before you trash memory beyond what is allocated for the copy target, and stop when you're at the end of the copy source.

For a contrived example, let's say the strings are always exactly 3 characters long (so the string would be 4 characters, gotta have the null character as a terminator for it to be a string):

Code: [Select]
for (i=0; i<4; i++)
 disp[0][i] = inString[i];

We really want to use the strcpy() function, like so:

Code: [Select]
strcyp(disp[0], inString);
but we still need to do the test to make sure inString isn't longer that the size of disp[0] (otherwise we trash memory, starting with disp[1], most likely, and working our way on from there).

-j

* without some C++ code and overloading the "=" operator

kg4wsv

Oh yeah, in my experience, there are no "quick" pointer questions.   :)

-j


timmaah

Sweet.. thanks for the quick reply. I do believe that makes sense and I understand it...

I think at this point there are bits and bytes of about 7 or 8 different coding langs in my head.. C being the newest..

I'll follow up in a bit on if I could get it to work or not..

thanks again

timmaah

for (i=0; i<4; i++)
 disp[0] = inString;

Works for what I needed...

Thanks


follower

Quote
That's why there are functions like strcpy() in the standard C library (but probably not in Arduino's library, due to microcontroller size constraints).

Actually, code with strcpy(NULL,NULL); compiles quite happily in IDE.

Quote
We really want to use the strcpy() function, like so:

Code: [Select]
strcyp(disp[0], inString);


For the sake of completeness, that snippet features a typo in the function name, it should really be:
Code: [Select]
strcpy(disp[0], inString);

--Phil.

mem

#6
Feb 08, 2008, 05:45 pm Last Edit: Feb 08, 2008, 05:48 pm by mem Reason: 1
The arduino supports strlcpy so furthering the interest in completeness you could do this:

Code: [Select]
strlcpy(disp[0], inString, sizeof(disp[0])) ;  
its advantage over strcpy is that it will never overwrite the destination buffer

kg4wsv

Nice, I didn't realize strcpy() and friends were available.  Did you notice what the program size penalty is when using them?

-j


mem

The first call to strlcpy adds 70 bytes, the second call adds another 38. Using a for loop instead of strlcpy for the second call only saves 18 bytes.

The first call to strcpy uses 30 bytes less than the safer strlcpy but that gets eroded in the check one should use with strcpy to make sure the buffer is big enough  ;)

IMO,  strlcpy is lean enough to be used in most any sketch where strings need to be copied

Go Up