2

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

2 Answers 2

1

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.

Sign up to request clarification or add additional context in comments.

7 Comments

Yes but wouldn't that turn "pointers of arrays" into "pointers of pointers"?
If a pointer variable is assigned the address of an object, it points to the object. It doesn't matter if the object is dynamically allocated or not. Dereferencing the pointer obtains the pointed to object.
Well, first of all the code you provided doesn't compile (pa + i needs to be dereferenced). Secondly, where is the array that's being pointed to? You might be onto something but I'll have to experiment some more.
@80m: Sorry about that. My brain is not a high quality C compiler.
Your edit appears to be correct. I'm impressed. How did you come up with that? I thought it would be an array of char*.
|
1

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!

1 Comment

Yes but what if I changed the LIST_SIZE to 3? The same problem would occur except this time with the txt1 variable.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.