mardi 1 décembre 2020

gdb prints long values watching a variable set with rand()

I'm using a gdb script to watch the changes of a variable using awatch:

#!/bin/bash

# Compile
gcc -Wall -pedantic -g -o demo demo.c

# Exit on compile error
if [ $? -ne 0 ]; then
    exit
fi

# Overwrite the contents of trace.gdb with a title
echo "# Watch var" > trace.gdb

# Don't stop each time there is a pagination
echo "set pagination off" >> trace.gdb

# Set a breakpoint in order to read the var address
echo "break main" >> trace.gdb

# Run the debugger
echo "run" >> trace.gdb

# Set watchpoint
echo "awatch var" >> trace.gdb

# Don't stop on each watchpoint (just show the trace)
echo "commands" >> trace.gdb
echo "continue" >> trace.gdb
echo "end" >> trace.gdb

# Start monitoring
echo "continue" >> trace.gdb

# Exit the debugger
echo "quit" >> trace.gdb

# Run the generated script
gdb -quiet -command=trace.gdb demo

The program:

/* demo.c */
#include <stdio.h>

int main(void)
{
    int var = 0;

    for (int i = 0; i < 5; i++)
    {
        var++;
    }
    printf("%d\n", var);
    return 0;
}

The ouptut seems correct:

Hardware access (read/write) watchpoint 2: var

Value = 0
main () at demo.c:7
7       for (int i = 0; i < 5; i++)

Hardware access (read/write) watchpoint 2: var

Old value = 0
New value = 1
main () at demo.c:7
7       for (int i = 0; i < 5; i++)

Hardware access (read/write) watchpoint 2: var

Old value = 1
New value = 2
main () at demo.c:7
7       for (int i = 0; i < 5; i++)

Hardware access (read/write) watchpoint 2: var

Old value = 2
New value = 3
main () at demo.c:7
7       for (int i = 0; i < 5; i++)

Hardware access (read/write) watchpoint 2: var

Old value = 3
New value = 4
main () at demo.c:7
7       for (int i = 0; i < 5; i++)

Hardware access (read/write) watchpoint 2: var

Old value = 4
New value = 5
main () at demo.c:7
7       for (int i = 0; i < 5; i++)

Hardware access (read/write) watchpoint 2: var

Value = 5
0x0000555555555176 in main () at demo.c:11
11      printf("%d\n", var);
5

But if I switch to this code using rand():

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main(void)
{
    int var = 0;

    srand((unsigned)time(NULL));
    for (int i = 0; i < 10; i++)
    {
        var = rand() % 10;
    }
    printf("%d\n", var);
    return 0;
}

and run the same script, gdb starts printing wrong values:

Breakpoint 1, main () at demo.c:6
6   {
Hardware access (read/write) watchpoint 2: var

Hardware access (read/write) watchpoint 2: var

Value = 0
main () at demo.c:9
9       srand((unsigned)time(NULL));

Hardware access (read/write) watchpoint 2: var

Old value = 0
New value = 32015002
0x00005555555551f8 in main () at demo.c:12
12          var = rand() % 10;

Hardware access (read/write) watchpoint 2: var

Value = 32015002
0x00005555555551fb in main () at demo.c:12
12          var = rand() % 10;

Hardware access (read/write) watchpoint 2: var

Old value = 32015002
New value = 7
main () at demo.c:10
10      for (int i = 0; i < 5; i++)

Hardware access (read/write) watchpoint 2: var

Old value = 7
New value = 84992124
0x00005555555551f8 in main () at demo.c:12
12          var = rand() % 10;

Hardware access (read/write) watchpoint 2: var

Value = 84992124
0x00005555555551fb in main () at demo.c:12
12          var = rand() % 10;

Hardware access (read/write) watchpoint 2: var

Old value = 84992124
New value = 6
main () at demo.c:10
10      for (int i = 0; i < 5; i++)

Hardware access (read/write) watchpoint 2: var

Old value = 6
New value = 55442740
0x00005555555551f8 in main () at demo.c:12
12          var = rand() % 10;

Hardware access (read/write) watchpoint 2: var

Value = 55442740
0x00005555555551fb in main () at demo.c:12
12          var = rand() % 10;

Hardware access (read/write) watchpoint 2: var

Old value = 55442740
New value = 0
main () at demo.c:10
10      for (int i = 0; i < 5; i++)

Hardware access (read/write) watchpoint 2: var

Old value = 0
New value = 208731384
0x00005555555551f8 in main () at demo.c:12
12          var = rand() % 10;

Hardware access (read/write) watchpoint 2: var

Value = 208731384
0x00005555555551fb in main () at demo.c:12
12          var = rand() % 10;

Hardware access (read/write) watchpoint 2: var

Old value = 208731384
New value = 3
main () at demo.c:10
10      for (int i = 0; i < 5; i++)

Hardware access (read/write) watchpoint 2: var

Old value = 3
New value = 114916873
0x00005555555551f8 in main () at demo.c:12
12          var = rand() % 10;

Hardware access (read/write) watchpoint 2: var

Value = 114916873
0x00005555555551fb in main () at demo.c:12
12          var = rand() % 10;

Hardware access (read/write) watchpoint 2: var

Old value = 114916873
New value = 9
main () at demo.c:10
10      for (int i = 0; i < 5; i++)

Hardware access (read/write) watchpoint 2: var

Value = 9
0x0000555555555216 in main () at demo.c:14
14      printf("%d\n", var);
9

I have read this post: gdb prints wrong values when modifying arguments and compiled with -fvar-tracking but it doesn't help.

Why this behaviour with rand()?




How could I avoid the pc to pick the same number?

If I have an array like this

int numbers[10] = {1,1,3,3,5,5,7,7,8,8};

And I want to pick one randomly

i = numbers[rand()% 10];

How could I avoid the pc to pick the same number more than twice for this example. Because like you can see in the array the same number is repeated 2 times. So I would like, for example, the number 8 to be choose just twice and same for the other numbers.

I know that I could do something like mark an element as "deleted", e.g., by setting it to 0, then if the number chosen has been deleted, you choose again. But I don't know how to do it properly, so If anyone here can help me I would be very grateful.




Problem with ransom selected user compare [duplicate]

I have a pool of players.

users

3 players should be selected at random from this pool.

user1 = random.choice (users)
user2 = random.choice (users)
user3 = random.choice (users)

How can I prevent a player from being randomly selected two or three times? And if so, how do I have the duplicate variable selected again at random?

For Example:

user1 = random select Smith

user2 = random select Douglas

user3 = random select Smith

The bot will recognize that Smith was randomly selected twice. Now the bot should randomly select user3 again.

Thank you for your help.




How to stop string repetition on array

We I have this college assignment where I have to Read a file with a list of names and add up to 3 presents to each one. I can do it but the presents are repeating and some people in the list are getting the same present more than once. How can I stop it so each person receives different variety of present each time?

Here is my code:

public static void main(String[] args) throws IOException {

        String path = "Christmas.txt";
        String line = "";

        ArrayList<String> kids = new ArrayList<>();
        FileWriter fw = new FileWriter("Deliveries.txt");
        SantasFactory sf = new SantasFactory();

        try (Scanner s = new Scanner(new FileReader("Christmas.txt"))) {
            while (s.hasNext()) {
                kids.add(s.nextLine());
            }

        }
        for (String boys : kids) {
            ArrayList<String> btoys = new ArrayList<>();

            int x = 0;
            while (x < 3) {
                if (!btoys.contains(sf.getRandomBoyToy().equals(sf.getRandomBoyToy()))) {
                    btoys.add(sf.getRandomBoyToy());
                    x++;

                }
                
            }

            if (boys.endsWith("M")) {

                fw.write(boys + " (" + btoys + ")\n\n");

            }

        }


        fw.close();

    }
}



Regex match group with elements in random order

For simplicity sake, let's say I have the following literal string:

abc[4;?;z;*]def

where 4, ?, z and * can appear in random order, are separated by a ; , and are characters (or strings) that i know beforehand.

I have this regex that matches the string using 'or' groups:

abc\[(?:z|\*|4|\?|\;)+\]def

The problem is that is still matching if one of the elements is missing in the string, and I want to check if all are present:

abc[?;z;*]def

Capturing groups are irrelevant for me. I just want to confirm the whole string.




Random string generator in c++ returns the same value in loops

I have a function that generates random string in my program and that works as I want, but only separately from loops. When I use it in loop in main(), it returns the same string every time (let's say 20 for example). Here is that function:

string randomString()
{
string c;
int r = NULL;
int num = 7;
srand(time(NULL));
for (int i = 0; i < num; i++)
{
    r = rand() % 26;
    c += 'a' + r;   
}
cout << "Random string: " << c << " \n";
return c;
}

What should I do to make it return different string every loop? Thanks for any help.




Is there an algorithm for random generation of circles in 2D?

Hi I am currently working on a space game in C++ with SFML. I have a 2D Vector which is my map. I want to create a random map where there will be randomly positioned and sized Planets in the map [As in example below.].

Planets shouldn't be touching or shouldn't overlap each other.

Right now idea is that I have a Class Planet that contains its center size_t i, j; and radius unsigned short r; and I want to create such random generator of pairs (point in 2D - center and radius of the planet). Either that or if there is completely different approach for this kind of problem I would be happy to hear it.

What I want to acomplish.

Note - there can be random number or planets. Doesn't matter if the map is packed or half empty.

This [↓] two touches sholdn't occur.

What I 100% don't want.