1

I have an array of pointers to structs.

struct key {          
  int *data;          
};                    

struct key *entry = NULL;
entry = malloc(sizeof(entry));

Reallocated a bit of times:

node = realloc(node, (length+1)*sizeof(node[0]));
node[length].data = some_int;

In another part of my program, I want to iterate through it. I don't know how much elements it is containing at the moment.

for (i=0; &(node[i]) != NULL; i++)
  length = i;                     

But I have infinity loop. Because:

(gdb) p node[i]
$1 = {data = 0x0}

It seems to like an uninitialized value, but it is not NULL pointer.

How to determine the end of an array?

Why it is not NULL pointer?

7
  • 1
    realloc does not initialise the new memory blocks which it has allocated to 0, if you want that thing you have to do it yourself. But I recommend you to store the "used" length somewhere, and only iterate through that length, since the "empty" blocks are don't matter. (of course store the allocated length somewhere else, to know, how much blocks you have left) Commented May 25, 2014 at 12:05
  • node is of which type? And if is of struct key * why do you assign "some int" to a pointer to int, that is a int *? Commented May 25, 2014 at 12:08
  • Why don't you use the length that you used to resize? Commented May 25, 2014 at 12:21
  • 1
    I like better the approach using a NULL-terminated array like proposed in your answer ... @MohitJain Commented May 25, 2014 at 12:33
  • 1
    An "uninitialized" variable can have any value, from null to garbage to a valid address (which may or may not address in item corresponding to the pointer's type). You can assume nothing about an uninitialized pointer, other than you shouldn't use it for anything. Commented May 25, 2014 at 12:34

2 Answers 2

2

&(node[i]) takes the address of node[i].

So

&(node[i]) != NULL

will always be true, as the address of node[i] will always be different from NULL.

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

Comments

1

&(node[i]) is same as node + i and as long as node is not null and i is not zero, this will be non-null.

If you want to mark end of array, I would suggest always (re)allocate one extra element and initialize pointer member of termination with NULL.

struct key *temp = realloc(node, (length+2)*sizeof(node[0]));
if(NULL == temp) {  /* Updated as per suggestion from @alk */
  /* Handle error and return */
}
node = temp;
node[length].data = address_of(some_int);
node[length+1].data = NULL;

And later while looping

for (i=0; node[i].data != NULL; i++)
  length = i;

But an even better solution would be to keep length you last used to realloc bundled with node. This way you won't need to calculate it using a loop.

4 Comments

For completeness on how to use realloc() it would be nice to see realloc() have its result assigned to a temporary pointer, which then is used to test for success and only then will overwrite the pointer which had been passed to realloc(). If not doing so a leak is produced if realloc() failed.
@alk Thank you for pointing. man pages say internally free is called on previous pointer only when memory is moved.
I do not understand what you want to express by man-page's quote? However your edit Iike .. :-)
@alk I meant I understood your point. I did not notice that if realloc returns NULL, there would be no move and thus no inclusive free. After the node pointer is rewritten there is no way to free mem.

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.