0

I am aligning several arrays in order and performing some sort of classification. I created an array to hold other arrays in order to simplify the operations that I want to perform.

Sadly, my program crashed when I ran it and I went on to debug it to finally realize that the sizeof operator is giving me sizes of pointers and not arrays within the loop.So I resorted to the cumbersome solution and my program worked.

How can I avoid this cumbersome method? I want to calculate within a loop!

#include <iostream>
#include <string>

#define ARRSIZE(X) sizeof(X) / sizeof(*X)

int classify(const char *asset, const char ***T, size_t T_size, size_t *index);

int main(void)
{
    const char *names[] = { "book","resources","vehicles","buildings" };

    const char *books[] = { "A","B","C","D" };
    const char *resources[] = { "E","F","G" };
    const char *vehicles[] = { "H","I","J","K","L","M" };
    const char *buildings[] = { "N","O","P","Q","R","S","T","U","V" };

    const char **T[] = { books,resources,vehicles,buildings };

    size_t T_size = sizeof(T) / sizeof(*T);
    size_t n, *index = new size_t[T_size];

    /* This will yeild the size of pointers not arrays...
        for (n = 0; n < T_size; n++) {
            index[n] = ARRSIZE(T[n]);
        }
    */

    /* Cumbersome solution */
    index[0] = ARRSIZE(books);
    index[1] = ARRSIZE(resources);
    index[2] = ARRSIZE(vehicles);
    index[3] = ARRSIZE(buildings);

    const char asset[] = "L";

    int i = classify(asset, T, T_size, index);

    if (i < 0) {
        printf("asset is alien !!!\n");
    }
    else {
        printf("asset ---> %s\n", names[i]);
    }

    delete index;
    return 0;
}

int classify(const char *asset, const char ***T, size_t T_size, size_t *index)
{
    size_t x, y;

    for (x = 0; x < T_size; x++) {
        for (y = 0; y < index[x]; y++) {
            if (strcmp(asset, T[x][y]) == 0) {
                return x;
            }
        }
    }
    return -1;
}
  • 6
    I would suggest you use a `std::vector>`. – NathanOliver Jun 22 '16 at 11:54
  • 3
    You have tagged both C++ and C. Your code mixes C++ headers (`iostream`, `string`) and C functions (`printf, strcmp`). Please pick a single language. – Andrew Jun 22 '16 at 11:56
  • what could be the Problem if we mix both languages? Compiler won't complain. Is there any risk? or it is just nice to have one language? c++ is super to c. Everything in c has been in c++ now. – Wafeeq Jun 22 '16 at 12:07
  • 2
    @GulluButt no. Valid C programms were not always valid C++ program even in 2000, and now there are way more differences. – Revolver_Ocelot Jun 22 '16 at 12:13
  • @Revolver_Ocelot what about Efficiency? I don't think so a valid program in c is not valid in c++ ? may be from Memory Management Point of view? efficency? – Wafeeq Jun 22 '16 at 12:32
  • @GulluButt, more like from simple language rules point of view. Implicit casting from `void*` comes to mind. Which doesn't happen in `c++` and is [good practice in `c`](http://stackoverflow.com/a/605858/817643). – StoryTeller - Unslander Monica Jun 22 '16 at 12:40
  • @GulluButt [Example of difference between implicit conversion rules](http://coliru.stacked-crooked.com/a/1824c4f573dc9bf8) – Revolver_Ocelot Jun 22 '16 at 12:45

3 Answers3

4

As you are including <string> and <iostream> I assume that the question is about C++ and not C. To avoid all this complication, simply use containers. E.g:

#include <vector>

std::vector<int> vect = std::vector<int>(3,0);
std::cout << vect.size() << std::endl;           // prints 3
463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185
2

One solution if you are coding in C is to terminate your array with a special item, like NULL

const char *books[] = { "A","B","C","D", NULL };

size_t size(const char *arr[])
{
    const char **p = arr;

    while (*p)
    {
        p++;
    }

    return p - arr;
}
Serve Laurijssen
  • 9,266
  • 5
  • 45
  • 98
0

You can specify the array size explizit:

size_t n, index[] = {ARRSIZE(books), ARRSIZE(resources), ARRSIZE(vehicles), ARRSIZE(vehicles)};

or if you want to avoid double typing you can you X-Macros to roll out everything:

#define TBL      \
    X(books)     \
    X(resources) \
    X(vehicles)  \
    X(buildings)

    const char **T[] = { 
#define X(x) x,
TBL
    };
#undef X

    size_t n, index[] = {
#define X(x) ARRSIZE(x),
TBL
};

which produces the same. See Running Demo.

kwarnke
  • 1,424
  • 1
  • 15
  • 10