the_naive
the_naive

Reputation: 3064

Mistake with returning data structure that returns array of type char*

I'm trying to return a data structure from a function named urlTokener where in the data structure one member is an array of type char* and the other is int. When I print the values of the array in the function urltokener I get the correct type, but I see that in the main function where the returned data structure is used, the array doesn't contain the right values as the output is not right(not the same as in the function). It seems the function is not returning the data structure correctly. Could you please check and say what I'm doing wrong in the following code?

#include <string.h>
#include <stdio.h>

struct tokenDetail
{
    char* theArray[256];

    int sizeOfArray;
};


tokenDetail urlTokener(const char *,char* );

void main()
{
    // String to be splitted.
    const char* url="/v1/AUTH_abb52a71-fc76-489b-b56b-732b66bf50b1/images?limit=1000&delimiter=/&format=xml"  ;

    tokenDetail newdetails;
    newdetails=urlTokener(url,"?");
    for (int i=0;i<newdetails.sizeOfArray;i++)
    {
        printf("This is in main where size is %d  and the value %s\n",newdetails.sizeOfArray,newdetails.theArray[i]);
    }
}

tokenDetail urlTokener(const char* urlLine,char* delimiter)
{
    char urlArray[256];
    strncpy(urlArray, urlLine, sizeof(urlArray));
    tokenDetail details;
    unsigned int index = 0;
    details.theArray[index] = strtok(urlArray, delimiter);

    while(details.theArray[index] != 0)
    {
        printf("This is in function %s\n",details.theArray[index]);
        ++index;
        details.theArray[index] = strtok(0, delimiter);
    }
    for (int i=0;i<index;i++)
    {
        printf("This is in function 2nd time %s\n",details.theArray[i]);
    }
    details.sizeOfArray=index;
    return details;
}

Please note : I'm doing it for c++, but I'm not allowed(by the person who gave me this task) to use namespace std, and library string. Which is why the code is similar to C. Because of this limitation I'm confused whether to tag it C or C++. So I tagged it in both c and c++. May be you could decide yourself.

Upvotes: 2

Views: 179

Answers (3)

James Kanze
James Kanze

Reputation: 153909

You're filling the array with pointers returned from strtok, which in turn are pointers into your urlArray, a local variable, which ceases to exist once you return from the function.

Is this C or C++? You've set both labels, and the solution is different. In C++, the obvious solution is to replace the char* in tokenDetail with std::string. In C, it's a bit more complicated. You have dynamically allocate the strings in your struct (using the non-standard but widely available strdup), and require the client to free them. The usual solution here is to return a pointer to a dynamically allocated TokenDetail, and a freeTokenDetail function which the client is required to call on the returned pointer. This gives you total freedom in how you do your allocations and frees. (The usual solution is, in fact, to only provide a forward declaration of TokenDetail to the clients, and to provide functions which they have to call to access its elements.)

Upvotes: 3

Gorpik
Gorpik

Reputation: 11028

The problem here is not that tokenDetail needs any handwritten copy constructor, destructor or assignment operator, which it doesn't. The problem is that the local variable urlArray is destroyed when you leave urlTokener(), so the positions pointed to by the elements of details.theArray become invalid. And, of course, the same happens with the returned tokenDetail, which is a copy of it.

Upvotes: 2

Luchian Grigore
Luchian Grigore

Reputation: 258558

You didn't implement the copy constructor, destructor or assignment operator.

Because you return by value, the copy constructor is called on return details;, but the default one only does a shallow copy, so the field char* theArray[256]; isn't copied properly.

Upvotes: 0

Related Questions