Dear frends Below this lines you´ll find a piece of code that does not work in the lines markedlike this *(route[3] + index) = *(y + index); // No change My application requires a string table with diferent information in each row, I tried several methods but it doesn´t work, if I assign then directly or if I assign a straigth string it works, but if I assigng from a different variable it doesn´t. Could you please help me..... Thanks Marco Olivares
void main(void) { char *route[5]; char *y; char x[5]; char c, index; // EnableInterrupts; /* enable interrupts */ SOPT_COPE = 0; route[0] = "This lines"; route[1] = "work"; route[2] = "fine if I"; route[3] = "assign them"; route[4] = "directly"; for (c = 0 ; c < 5 ; c++) { route[c] = "message"; } y= "FREE"; for (index = 0 ; index < 4; index ++) { route[1][index] = y[index]; // No change x [index] = y[index]; } x[index] = '\0'; y= "free"; for (index = 0 ; index < 4; index ++) { *(route[2] + index) = y[index]; // No change *(x + index) = y[index]; } x[index] = '\0'; y= "scal"; for (index = 0 ; index < 4; index ++) { *(route[3] + index) = *(y + index); // No change *(x + index) = *(y + index); } x[index] = '\0'; for(;;) { } }
Hi Marquinho,
I changed your code so it does what you would like.
The problem, as someone already said, is that if in your code you write:
route[0] = "This lines";
route[0] points to somewhere in flash memory where there is the string "burned" on flash.
After you try to change the single charachters, but you try to change a flash cell as if it was a RAM cell, you can't.
With my code, strings are initialized and put in RAM.
Before each "for loop" , I made route[?] point to RAM, so I can write something on it.
Of course, you waste precious RAM cells to store strings.
Hope it helps.
#include <hidef.h> /* for EnableInterrupts macro */ #include "derivative.h" /* include peripheral declarations */ char string0[]= "This lines"; char string1[]= "work"; char string2[]= "fine if I"; char string3[]= "assign them"; char string4[]= "directly"; char *route[5] = {string0, string1, string2, string3, string4}; char *y; char x[5]; char c, index; void main(void) { EnableInterrupts; /* enable interrupts */ /* include your code here */ // EnableInterrupts; /* enable interrupts */ //SOPT_COPE = 0; /* route[0] = "This lines"; route[1] = "work"; route[2] = "fine if I"; route[3] = "assign them"; route[4] = "directly"; */ for (c = 0 ; c < 5 ; c++) { route[c] = "message"; } route[1] = string1; y= "FREE"; for (index = 0 ; index < 4; index ++) { (route[1])[index] = y[index]; // No change x [index] = y[index]; } x[index] = '\0'; route[2] = string2; y= "free"; for (index = 0 ; index < 4; index ++) { *(route[2] + index) = y[index]; // No change *(x + index) = y[index]; } x[index] = '\0'; route[3] = string3; y= "scal"; for (index = 0 ; index < 4; index ++) { *(route[3] + index) = *(y + index); // No change *(x + index) = *(y + index); } x[index] = '\0'; for(;;) { __RESET_WATCHDOG(); /* feeds the dog */ } /* loop forever */ /* please make sure that you never leave main */ }
Hi BV_BV
Master, finally some one gave me a response. Thanks your code is great, with your explanation I understood why that things occured. I think that the lines
char string0[]= "This lines";
char string1[]= "work";
char string2[]= "fine if I";
char string3[]= "assign them";
char string4[]= "directly";
char *route[5] = {string0, string1, string2, string3, string4};
breaks the "link" that I had.
Thanks for your valuable help, and I'll keep in mind to store as few strings as my appliication needs!
Regards
Marco Olivares
The route[x] pointers have to refer to properly allocated, writable memory.
In the code snippet provided they point into string literals ("message"), so what the code
effectively does is trying to modify that string (pseudo code, may or may not compile):
"message"[0] = 'M';
If "message" is allocated in flash (default), then assigning to it would work at runtime.
(Note that the ANSI C standard calls this "undefined behavior", meaning anything can happen, it can even work on some compilers. Just don't write into string literals...)
So if you want to be able to modify route[x][y], assign it to a buffer:
char buf[100000000];
route[0]= buf;
route[0][0] = 'H';
route[0][1] = '\0';
(or strcpy(route[0], "H")
Make sure buf is big enough for your string, it probably should not be 100000000 bytes though :smileywink:
I would suggest you search the web for articles describing how pointers and array work in C, I'm sure there are plenty of good references.
BTW: Be aware that on a HC08 the stack is limited. Allocating too huge buffers on the stack will cause strange effects when executing (stack overflow). Allocating too huge buffers globally will cause the linking step to fail.
Daniel
Hi....
I did the buff assigment with not a better response. Also I use malloc() to reserve memory. That works fime but changes to the entite ponter array is done, please check code above!
Thanks
#include <hidef.h> /* for EnableInterrupts macro */
#include "derivative.h" /* include peripheral declarations */
#include <stdlib.h>
#include <string.h>
void main(void) {
volatile char *route[5];
volatile char *y;
volatile char x[5];
char c, index;
SOPT_COPE = 0;
y = malloc(50 * sizeof(char)); // ALWAYS OK.
route[0] = malloc(50 * sizeof(char)); // ALWAYS OK.
route[1] = malloc(50 * sizeof(char)); // ALWAYS OK.
route[2] = malloc(50 * sizeof(char)); // ALWAYS OK.
route[3] = malloc(50 * sizeof(char)); // ALWAYS OK.
route[4] = malloc(50 * sizeof(char)); // ALWAYS OK.
route[0] = "This lines";
route[1] = "work";
route[2] = "fine if I";
route[3] = "assign them";
route[4] = "directly";
for (c = 0 ; c < 5 ; c++)
{
route[c] = "message ok";
}
//*********************************************************************************
x[0]= 'F';
x[1]= 'R';
x[2]= 'E';
x[3]= 'E';
x[4]= '\0';
y = x;
route[0] = y;
x[0]= 'f'; //After this line route[0][0] changes 'F' to 'f'
x[1]= 'r'; //After this line route[0][1] changes 'R' to 'r'
x[2]= 'e'; //After this line route[0][2] changes 'E' to 'e'
x[3]= 'e'; //After this line route[0][3] changes 'E' to 'e'
x[4]= '\0';
y = x;
route[1] = y;
x[0]= 's'; //After this line route[0][0] and route[1][0] changes 'f' to 's'
x[1]= 'c'; //After this line route[0][1] and route[1][1] changes 'r' to 'c'
x[2]= 'a'; //After this line route[0][2] and route[1][2] changes 'e' to 'a'
x[3]= 'l'; //After this line route[0][3] and route[1][3] changes 'e' to 'l'
x[4]= '\0';
y = x;
route[2] = y;
//*********************************************************************************
x[0]= 'F'; //After this line route[0][0] and route[1][0] changes 's' to 'F'
x[1]= 'R'; //After this line route[0][1] and route[1][1] changes 'c' to 'R'
x[2]= 'E'; //After this line route[0][2] and route[1][2] changes 'a' to 'E'
x[3]= 'E'; //After this line route[0][3] and route[1][3] changes 'l' to 'E'
x[4]= '\0';
(void) strcpy(y,x);
route[0] = y;
x[0]= 'f'; //After this line route[0][0] and route[1][0] changes 'F' to 'f'
x[1]= 'r'; //After this line route[0][1] and route[1][1] changes 'R' to 'r'
x[2]= 'e'; //After this line route[0][2] and route[1][2] changes 'E' to 'e'
x[3]= 'e'; //After this line route[0][3] and route[1][3] changes 'E' to 'e'
x[4]= '\0';
(void) strcpy(y,x);
route[1] = y;
x[0]= 's'; //After this line route[0][0] and route[1][0] changes 'f' to 's'
x[1]= 'c'; //After this line route[0][1] and route[1][1] changes 'r' to 'c'
x[2]= 'a'; //After this line route[0][2] and route[1][2] changes 'e' to 'a'
x[3]= 'l'; //After this line route[0][3] and route[1][3] changes 'e' to 'l'
x[4]= '\0';
(void) strcpy(y,x);
route[2] = y;
//*********************************************************************************
x[0]= 'F'; //After this line route[0][0] and route[1][0] changes 's' to 'F'
x[1]= 'R'; //After this line route[0][1] and route[1][1] changes 'c' to 'R'
x[2]= 'E';
x[3]= 'E';
x[4]= '\0';
*y = *x;
*(y+1) = *(x+1);
*(y+2) = *(x+2);
*(y+3) = *(x+3);
*(y+4) = *(x+4);
route[0] = y;
x[0]= 'f'; //After this line route[0][0] changes 'F' to 'f'
x[1]= 'r'; //After this line route[0][1] changes 'R' to 'r'
x[2]= 'e'; //After this line route[0][2] changes 'E' to 'e'
x[3]= 'e'; //After this line route[0][3] changes 'E' to 'e'
x[4]= '\0';
*y = *x;
*(y+1) = *(x+1);
*(y+2) = *(x+2);
*(y+3) = *(x+3);
*(y+4) = *(x+4);
route[1] = y;
x[0]= 's'; //After this line route[0][0] and route[1][0] changes 'f' to 's'
x[1]= 'c'; //After this line route[0][1] and route[1][1] changes 'r' to 'c'
x[2]= 'a'; //After this line route[0][2] and route[1][2] changes 'e' to 'a'
x[3]= 'l'; //After this line route[0][3] and route[1][3] changes 'e' to 'l'
x[4]= '\0';
*y = *x;
*(y+1) = *(x+1);
*(y+2) = *(x+2);
*(y+3) = *(x+3);
*(y+4) = *(x+4);
route[2] = y;
//*********************************************************************************
y= "FREE";
for (index = 0 ; index < 4; index ++)
{
route[1][index] = y[index]; // No change
x [index] = y[index];
}
x[index] = '\0';
y= "free";
for (index = 0 ; index < 4; index ++)
{
*(route[2] + index) = y[index]; // No change
*(x + index) = y[index];
}
x[index] = '\0';
y= "scal";
for (index = 0 ; index < 4; index ++)
{
*(route[3] + index) = *(y + index); // No change
*(x + index) = *(y + index);
}
x[index] = '\0';
for(; {
}
}
If you use a single buffer for multiple array elements then obviously changing that buffer affects all its uses.
Using malloc, well that is not usually done for a S08. Also using malloc without free is wrong, I
would try not to do that even for sample/test code. Did you look around for a book about learning C?
I definitely recomment to try things out when you learn a language, but learning without a guide (as a C book)
is not that efficient for a complex language like C.
char *route[2];char buf0[10];char buf1[10];route[0] = buf;route[1] = buf1;strcpy(route[0], "Hello");strcpy(route[1], "World");
Or, in by using an array of arrays (and not an array of pointers)
char route1[2][10];strcpy(route1[0], "Hello");strcpy(route1[1], "World");
Note that route1 and route from the previous sample are very different animals.
route contains pointers which have to point to some otherwise allocated memory, route1 contains (fixed length) arrays directly.
Daniel
Dear Daniel.....
With all my respect to you, I want to tell you that I feel offended with your comment!
But forget this (please) and let's back to work.....
Of course that I read a C book named "The C programming Language by Kernighan & Ritchie" and it tells that an array of pointers works as I need. But this time I do not know if CW syntax is taking different. 7 hours before your response I changed this application to "array of arrays" and it works well (more control but it finally works).
Thanks for your comments and your valuable help.
Marco Olivares