klefevre klefevre - 18 days ago 5
Objective-C Question

Double dimension tab count

I've forgotten how count a double dimension C array because I don't understand why this code return me a count of 12 instead of 6.

// My tab
static NSString *kStringTag[][2] = {
{@"string1", @"1"},
{@"string2", @"1"},
{@"string3", @"0"},
{@"string4", @"0"},
{@"string5", @"1"},
{@"string6", @"1"},
{nil, nil}
};

// My C func
unsigned int tablen(void **tab)
{
unsigned int i = 0;

while (tab[i] != nil)
i++;

return i;
}

- (void)viewDidLoad
{
NSLog(@"%d", tablen((void **)kStringTab));
}

pmg pmg
Answer

Your code is not C.

If it were C, tab would be an array of array of pointers to NSStrings (whatever that is).

In C an array of arrays of pointers to NSStrings is not necessarily compatible with a pointer to pointer to void ... so remove the casts and get the types correct.

In C, this works ...

#include <stdio.h>

static char *kStringTab[][2] = {
    {"string1", "1"},
    {"string2", "1"},
    {"string3", "0"},
    {"string4", "0"},
    {"string5", "1"},
    {"string6", "1"},
    {NULL, NULL},
};

unsigned int tablen(char *tab[][2]) {
  unsigned int i = 0;
  while (tab[i][0] != NULL) i++;
  return i;
}

int main(void) {
  printf("%d\n", tablen(kStringTab));
  return 0;
}

Suggestion: increase the warning level of your compiler and mind the warnings.


Edit: new generic version

#include <math.h>
#include <stdio.h>

static double anothertest[][3] = {
    {42, 54, -122},
    {33, -0.001, 0.001},
    {6, 0, 7},             /* 0 in middle: stop condition in nullp2 :) */
    {2, 2, 2},
};

static char *kStringTab[][2] = {
    {"string1", "1"},
    {"string2", "1"},
    {"string3", "0"},
    {"string4", "0"},
    {"string5", "1"},
    {"string6", "1"},
    {NULL, NULL},
};

int nullp2(const void *elem) {
  const double *tmp = elem;
  return (fabs(tmp[1]) < 0.000000001);
}

int nullp(const void *elem) {
  char (*const *tmp)[2] = elem; /* tmp is a pointer to each element of kStringTab */
  return ((*tmp)[0] == NULL);
}

unsigned int tablen(void *x, size_t size,
                    int (*check)(const void *)) {
  char *y = x;
  unsigned int i = 0;

  while (!check(y)) {

    i++;
    y += size;
  }
  return i;
}

int main(void) {
  printf("tablen returns %d\n",
        tablen(kStringTab, sizeof *kStringTab, nullp));
  printf("tablen returns %d\n",
        tablen(anothertest, sizeof *anothertest, nullp2));
  return 0;
}

You can see it running at ideone.