Problem with Creating list of random numbers

Go To Last Post
16 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello

This is my Code:

void Shuffle_List (short MP3_Sum, short *PlayList){
	
	short *Available_List;
	short MP3_Index = MP3_Sum;
	short i,k,Number=0;

	PlayList = (short *) malloc(MP3_Sum * sizeof(short));
	Available_List = (short *) malloc(MP3_Sum * sizeof(short));

	for(i=0;i

The result is in the appending .txt-File.

I did a test before, just writing random numbers in a txt-file, this worked brilliantly, the buffer is big enough.
But somethin with the lists ruins my output.
Where do the negative numbers come from? Is there an overflow, or something?

So please Guys, now it's your turn, to help me out.
Thank you

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Forget the random numbers you are doing something VERY dangerous in your code. You pass "Playlist" as a pointer into the Shuffle() function, you then malloc(), process and free(). But that means the function returns with the pointer still pointing at a block of memory that has now been freed. This is a classic pointer/malloc/free error. Try to get into the habit of always setting malloc'd pointers back to NULL after the free so that a "dirty" pointer is never inadvertently used.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You need to understand how negative numbers are represented. It's called "two's complement", and you will find an excellent article on it at Wikipedia.

In practice it means that when you've reached the largest positive number and add 1 you will wrap to the smallest negative number. So for a signed char (8 bits wide) that starts at 0 and is repeatedly incremented it would go:
0, 1, 2, 3, 4 ... 125, 126, 127, -128, -127, -126, -3, -2, -1, 0, 1, 2...

No the compiler will not generate any "overflow signal". It is up to you to take care of this in your code.

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Your array gets out of bounds:

      for (k = Number; k

And I do not quite see the point of your shuffle.

You could do a regular pass through the available list. Exchanging the current indexed entry with a random entry. This would involve MP3_Sum calls to rand(), and MP3_Sum exchanges.

e.g.

   for(i=0;i
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

@clawson
Did you see, that i only free the memory of the second list?
@Johan
Yes, i know about this fact, but i have declarated 'Number' as 'short' so with a 123 as my maximum Random-Value, there should be no problem, even as signed char.
There is no incrementation taking place in my code, that 'Number' would get negative.
@david
Thank you, i saw the problem in the for-loop, so i corrected it to

for (k = Number; k

I understand your approach, but i do the thing with the second list to exclude, the problem that a random number could appear twice.
Or do you know a method, how to generate a random-list?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

@clawson
Did you see, that i only free the memory of the second list?

No, sorry, I missed that - but this is almost worse isn't it? Each time you call Shuffle() you making an unbalanced malloc() - does the caller of Shuffle() known that it is their responsibility to free(Playlist)? (there's no evidence of it in the posted code - when you fclose() you should free() the pointer).

I'd suggest you:

Playlist=malloc();
Shuffle(Playlist);
Use Playlist
free(Playlist);

bringing the malloc() outside the Shuffle() function all together. It's unlikely that the later user of Shuffle() is going to realise that they are making a malloc() by using it. Suppose the later user thinks I want this list REALLY shuffled and does:

for(i=0; i<3; i++) {
 Shuffle(Playlist);
}

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

yes that's better. I moved the allocation out of the function.
But i can't free PlayList, because it is used all the time by my MP3-Player-Routine. That's why, there is no free()-instruction.

But do you have an idea, why i had negative numbers in my txt-file?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

But i can't free PlayList, because it is used all the time by my MP3-Player-Routine. That's why, there is no free()-instruction.

Then why are you using malloc()/free() if it's not dynamic? Why not just a global:

short Playlist[123];

This way, when you compile you'll know that 246 bytes are being set aside for this usage as they'll be listed in the static size report.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
I understand your approach, but i do the thing with the second list to exclude, the problem that a random number could appear twice.
Or do you know a method, how to generate a random-list?

None of the numbers will appear twice. You are only exchanging pairs. The random number can appear twice, but this just means that an item is swapped twice.

I suspect that your MP3 files may get added to, so you will need to do the dynamic allocation. However you are probably better off with allocating the largest array that you can, and using just the first MP3_Sum elements.

Regarding your -ve numbers, Number should go from 0 .. MP3_Sum-1. Array indices start at 0. So I am convinced that you are picking up an out of bounds element. Also rand() % N will give results 0 .. N-1. You are adding a 1 on top.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

123 is just an example value for testing, because the number of files on the sd-cards, that are put in the player, can be differing.

Ah! i just picked up the rand()-Routine from a tutorial. mmh obviously zero is excluded in this way.
But why should i allocate as much memory as possible? AVR-Studio tells me, that 87% of my Atmega-RAM are already used.
I will test the swap-version later on.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

AVR-Studio tells me, that 87% of my Atmega-RAM are already used.

Then where on God's green Earth do you imagine it's going to find the memory to service a malloc(246) request? With 87% used you are already over-budget. With normal stack/local usage levels you need that down at 75%..80% levels and if you want to fit it in a malloc heap too then take it another 250-300 bytes down from there (or however much you expect the maximum alloc'd at one time to be). You don't get owt for nowt in microcontrollers!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
where ... do you imagine it's going to find the memory to service a malloc(246) request?
I imagine that it is getting it from negative memory space, hence the negative numbers in the result :)

Regards,
Steve A.

The Board helps those that help themselves.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

So can you give me a hint, how to reduce the needed memory? I use FatFS and am using all jumpers to get a shrinked software, as i'm just needing to read from my SD-Card.
When i set it to readonly, the necessary memory is reduced by 3% not very much.

And then another question:
Compiler tells me: warning: passing argument 2 of 'Shuffle_List' makes pointer from integer without a cast
I looked at the internet, but couldn't assign the offered solutions to my problem.

Thanks

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

So can you give me a hint, how to reduce the needed memory?

Well make sure any non variant data including strings used in output are all in PROGMEM. I know you need one or more FafFs structures that "cost" about 560 bytes each but see if you can reuse some of that data space when FatFs is not being used.
Quote:

Compiler tells me: warning: passing argument 2 of 'Shuffle_List' makes pointer from integer without a cast

What did you expect if the code you now have is anything like the OP:

Shuffle_List(MP3_Sum, *PlayList);

Just out of interest, what purpose do you think the '*' in there is playing?

(hint: you are passing a value, not a pointer but the receiving routine has been told to expect a pointer. The compiler is telling you that it's converting a value into a pointer which may not be what you want (it isn't!!))

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

An SDCard MP3 Player needs a certain amount of SRAM. But with a bit of forethought, you can use a few tricks.

You may have 1000 tracks to shuffle, but only 512 byte to do it with. So shuffle 256 tracks at a time. Write your 'shuffled' 256 track array back to a disk sector.
Shuffle the next 256 tracks...

When you are done, you can use that 512 bytes as your disk sector buffer.

Looking at MP3 files on my PC, a typical track is 3MB. So a 2GB card will take 600 songs. A 16GB card will take 5000 songs.

It does not take much imagination to realise that you will need to shuffle in stages, and use your SDCard as a disk paging area.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank you clawson, as i am still a beginner in programming i sometimes have problems with the pointer-thing.

Regarding david's suggestion, how do i get the information, where a free sector is on the card?

I mean in ideal conditions, the files are written to a SC-Card, starting from sector 0 beginning in sequence without gaps. But in reallife, sometimes files are deleted or so, and than i have gaps.
How would you handle this? Is there a list in the FAT-structure, where the sector ranges of the files are saved?