Question

I'm doing a little programming experiment in C on ways to represent multiple lines of text.

I've come up with four ways: arrays of arrays, arrays of pointers, pointers of arrays, and pointers of pointers.

I've run into a little problem with pointers of arrays. Every time I create an array, it actually just reuses the array I already created.

Check out the output of the "pointers of arrays" (pa) part of my program to see what I mean:

variable    address         value
==========  ==============  =====
pa          0x10f500970

*(pa+0)     0x7fff6f0334bd

*(pa+0)[0]  0x7fff6f0334bd  t
*(pa+0)[1]  0x7fff6f0334be  e
*(pa+0)[2]  0x7fff6f0334bf  s
*(pa+0)[3]  0x7fff6f0334c0  t
*(pa+0)[4]  0x7fff6f0334c1
*(pa+0)[5]  0x7fff6f0334c2  0

*(pa+1)     0x7fff6f0334bd

*(pa+1)[0]  0x7fff6f0334bd  t
*(pa+1)[1]  0x7fff6f0334be  e
*(pa+1)[2]  0x7fff6f0334bf  s
*(pa+1)[3]  0x7fff6f0334c0  t
*(pa+1)[4]  0x7fff6f0334c1
*(pa+1)[5]  0x7fff6f0334c2  1

See how the address for each array are the same? Not very cool, is it?

So here's my question: Is there a way to actually declare a new array in a n > 1 loop, rather than rewrite the contents of the already existing array?

Here's the snipplet: (LIST_SIZE = 2 and TEXT_SIZE = 6)

void** pa = malloc(LIST_SIZE * sizeof(void*));

printh();

printf("pa\t\t%p\n\n", pa);

for(int i = 0; i < LIST_SIZE; i++)
{
  char txt[TEXT_SIZE + 1];

  sprintf(txt, "test %d", i);

  *(pa + i) = txt;

  printf("*(pa+%d)\t\t%p\n\n", i, *(pa + i));

  for(int j = 0; j < TEXT_SIZE; j++){
    printf("*(pa+%d)[%d]\t%p\t%c\n", i, j, &(((char*)*(pa+i))[j]), ((char*)*(pa+i))[j]);
  }

  printf("\n");
}

Thanks. If you have any other comments or suggestions, I'd be interested in hearing them, too.

The full source code is available at: https://gist.github.com/80m/7143558

Was it helpful?

Solution

The variable txt is local to the for loop. At each iteration, the old txt variable becomes invalid, and a different txt instance is created. This means the pointer that was assigned txt in the previous iteration is not pointing to a valid object when the next iteration starts.

When the loop is finished, none of your pointers point to anything valid.

One way to fix this is to dynamically allocate memory for each pointer you want to assign to.

    pa[i] = malloc(TEXT_SIZE+1);
    snprintf(pa[i], TEXT_SIZE+1, "test %d", i);

You say you want "pointers to arrays", yet you declared of void **pa, which makes pa a pointer to a pointer. If you want pa to a pointer to an array, you would declare it this way:

char (*pa)[TEXT_SIZE+1] = malloc(LIST_SIZE * sizeof(*pa));

So now, pa[0] would be one 7 byte array, and pa[1] would be a second 7 byte array. You do away with the need to do any dynamic allocation within the loop.

OTHER TIPS

Each time the loops runs pa points to the same txt. So, the address that pointer pa is pointing to remains the same. If you want to point this to another location then try creating a different char[], say txt1, and assign it to (pa+i) during second iteration.

I tried this:

int i=0,j=0;

void** pa = malloc(LIST_SIZE * sizeof(void*));

printf("pa\t\t%p\n\n", pa);

for(i = 0; i < LIST_SIZE; i++)
{

char txt[TEXT_SIZE + 1];
char txt1[TEXT_SIZE + 1];


  sprintf(txt1, "test %d", i);
  sprintf(txt, "test %d", i);
  if (i==0)
  {
    *(pa + i) = txt;
  }
  else
  {
    *(pa + i) = txt1;
  }

  printf("*(pa+%d)\t\t%p\n\n", i, *(pa + i));

  for(j = 0; j < TEXT_SIZE; j++){
    printf("*(pa+%d)[%d]\t%p\t%c\n", i, j, &(((char*)*(pa+i))[j]), ((char*)*(pa+i))[j]);
  }

  printf("\n");
}

and got different addresses for different iterations.

I think the problem is not with the pointer but with the variable it is trying to refer to and it remains the same variable every time. Hope this helps!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top