-1

I have created a method that returns a string as per the value of generated random number. This work as expected when the function is in the same program file where it is called.

But when I define this method in a new header file and then call it in a different file then it is returning same random number.

Defined method:

char* newTrafficGenerator(void)
{
    int i;
    int count =0;
    static char currentTrafficType[6];
    i = random_rand();
    printf("Current random no is: %d\n",i);
    if (i>0 && i<32767)
    {
        strncpy(currentTrafficType,"Type A",sizeof(currentTrafficType));
    }
    else if(i>32767 && i<55705)
    {
        strncpy(currentTrafficType,"Type B",sizeof(currentTrafficType));
    }
    else
    {
        strncpy(currentTrafficType,"Type C",sizeof(currentTrafficType));
    }   
    return currentTrafficType;
}

Called by following code:

static void generateInfiniteRandomNumber(void)
{
    int count=0;
    char *c;
    while(count<10)
    {
        c = newTrafficGenerator();
        printf("Type is %s\n",c);
        count++;
    }
}

The output when called in same file is:

Current random no is: 18547
Type is Type A
Current random no is: 56401
Type is Type C
Current random no is: 23807
Type is Type A
Current random no is: 37962
Type is Type B
Current random no is: 22764
Type is Type A
Current random no is: 7977
Type is Type A
Current random no is: 31949
Type is Type A
Current random no is: 22714
Type is Type A
Current random no is: 55211
Type is Type B
Current random no is: 16882
Type is Type A

When defined in a new header file and then output upon calling is:

Current random no is: 1920540202
Type is Type C
Current random no is: 1920540202
Type is Type C
Current random no is: 1920540202
Type is Type C
Current random no is: 1920540202
Type is Type C
Current random no is: 1920540202
Type is Type C
Current random no is: 1920540202
Type is Type C
Current random no is: 1920540202
Type is Type C
Current random no is: 1920540202
Type is Type C
Current random no is: 1920540202
Type is Type C
Current random no is: 1920540202
Type is Type C
Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
  • 1
    Perhaps you did not seed the random function when calling it from a different header ? could you please provide the body of `random_rand` – Ahmed Tounsi Dec 18 '19 at 12:58
  • 3
    `currentTrafficType` is too small. – molbdnilo Dec 18 '19 at 13:00
  • @yxor random_rand is provided by contiki itself. Please refer to https://github.com/contiki-os/contiki/blob/master/core/lib/random.h and https://github.com/contiki-os/contiki/blob/master/core/lib/random.c – SUBHANSHU SAHU Dec 18 '19 at 13:03
  • 1
    `currentTrafficType[6];` is too small; the buffer will not be nul-terminated (and: strncpy is almost allways wrong) – wildplasser Dec 18 '19 at 13:03
  • 1
    did you use `void random_init(unsigned short seed)` in the file ? – Ahmed Tounsi Dec 18 '19 at 13:04
  • @wildplasser Can you please guide how to resolve this? – SUBHANSHU SAHU Dec 18 '19 at 13:04
  • @yxor No I directly called the ```random_rand()``` function only – SUBHANSHU SAHU Dec 18 '19 at 13:05
  • 1
    that's your issue. @SUBHANSHUSAHU you cannot get a random number without seeding the generator first, try seeding it at the beginning of your program. – Ahmed Tounsi Dec 18 '19 at 13:06
  • @yxor I tried seeding as well but didn't get any success. Added ```random_init(50);``` as the first line of ```newTrafficGenerator``` method – SUBHANSHU SAHU Dec 18 '19 at 13:16
  • @SUBHANSHUSAHU, you're seeding the generator the same number before generating once, Of course you will get the same result. Please `#include ` then `random_init(time(NULL));` in the `generateInfiniteRandomNumber` function. – Ahmed Tounsi Dec 18 '19 at 13:18
  • How about trying to print the value of i? – Siddharth Dec 18 '19 at 13:18
  • @Siddharth I have updated the results – SUBHANSHU SAHU Dec 18 '19 at 13:29
  • 2
    @yxor No, that‘s bad advice. **Do not** reseed the random number generator needlessly. Seed it *once*, before doing all the other work. In fact, with your advice you will be guaranteed to generate the same random number several times in a row, because of the limited precision of `time`. – Konrad Rudolph Dec 18 '19 at 13:34
  • Try calling random_init() before calling the random_rand() – Siddharth Dec 18 '19 at 13:35
  • @Siddharth tried that as well but didn't get any success – SUBHANSHU SAHU Dec 18 '19 at 13:35
  • https://stackoverflow.com/questions/9711076/why-does-rand-always-return-the-same-value – Siddharth Dec 18 '19 at 13:43
  • @Siddharth As I stated in my post, this works as expected when ```newTrafficGenerator``` is in the same program file where it is called. The issue is occurring when I define it in a new header file and then call it. – SUBHANSHU SAHU Dec 18 '19 at 13:45
  • @KonradRudolph That's what i meant. perhaps I wasn't very clear in my choice of words. thank you for clearing it. – Ahmed Tounsi Dec 18 '19 at 13:51
  • @KonradRudolph Can you guide how to resolve this issue – SUBHANSHU SAHU Dec 18 '19 at 13:56
  • @SUBHANSHUSAHU Honestly, no. I can’t add anything to the discussion that hasn’t already been said. You need to edit your question to include a [complete, minimal reproducible example](https://stackoverflow.com/help/minimal-reproducible-example). Currently it’s unclear what the problem is. – Konrad Rudolph Dec 18 '19 at 13:57
  • I tried to reproduce, always getting type C but getting different random number everytime... Please elaborate on reproduction... – Siddharth Dec 18 '19 at 13:58
  • Now I'm getting expected (correct) output :P – Siddharth Dec 18 '19 at 14:01

1 Answers1

1

@wildplasser is right, you have undefined behavior in your program. All the discussion about seeding or no seeding is useless before you fix that issue. You need space for the null-terminator in currentTrafficType:

static char currentTrafficType[7];

Having the return value in a static local variable, is typically bad practice when it can be avoided. It makes your function non-reentrant, and thread-unsafe. In your case, the data you want to return, already exists as string literals, so you can drop the whole array:

/* return type modified from `char *` to `const char *` */
const char* newTrafficGenerator(void)
{
    int i;
    int count =0;

    /* Use pointer rather than array */
    const char *currentTrafficType;

    i = random_rand();
    printf("Current random no is: %d\n",i);
    if (i>0 && i<32767)
    {
        currentTrafficType = "Type A";
    }
    else if(i>32767 && i<55705)
    {
        currentTrafficType = "Type B";
    }
    else
    {
        currentTrafficType = "Type C";
    }   
    return currentTrafficType;
}

String literals are guaranteed to exist for the whole duration of your program, so we can pass them around by pointer value, rather than doing slow and cumbersome array copying. Just be aware that string literals are read-only and therefore should only be assigned to const char * and not char *.

HAL9000
  • 2,138
  • 1
  • 9
  • 20