How to use pointer arrays

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

How to use pointer arrays

2,203 Views
Marquinhjo
Contributor I
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(;;) {
 
  
 
    }
 
}
Labels (1)
0 Kudos
7 Replies

711 Views
BV_BV
Contributor III

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 */
}

 

 

 

Message Edited by BV_BV on 2009-04-04 08:05 AM
Message Edited by BV_BV on 2009-04-04 08:08 AM
0 Kudos

711 Views
Marquinhjo
Contributor I

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

0 Kudos

711 Views
CompilerGuru
NXP Employee
NXP Employee

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"):smileywink:

 

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

0 Kudos

711 Views
Marquinhjo
Contributor I

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(;:smileywink: {
 
  
 
    }
 
}
 

0 Kudos

711 Views
CompilerGuru
NXP Employee
NXP Employee

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

 

0 Kudos

711 Views
Marquinhjo
Contributor I

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

 

 

0 Kudos

711 Views
Lundin
Senior Contributor IV
K&R is a TERRIBLE book when it comes to learning good programming practice. Those two guys might be gurus, but they wrote that book long before anyone even knew the difference between good and bad programming. That book is the reason why so many fresh C programmers fear and don't understand pointers. It is a good book to learn the pure syntax from, but that's about it.

CW is following standard C, you can't copy data into pointers that don't point at allocated data, it is a very common beginner error. Also, when you set it to point at something like this

"This lines"

then it points to a constant string in non-volatile memory that can't be changed.

Dynamic allocation with malloc() is something mainly used in RAM-based systems (that is: PC). It consumes a lot of memory for a "heap", it is slightly slower than static allocation, and it can also lead to dangerous memory leaks. malloc() is therefore generally banned in the embedded industry.
0 Kudos