[C] Allocating memory for Dice Roller

  • (2 Pages)
  • +
  • 1
  • 2

29 Replies - 983 Views - Last Post: 10 November 2012 - 06:36 PM Rate Topic: -----

#1 Akasen  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 41
  • Joined: 13-August 12

[C] Allocating memory for Dice Roller

Posted 26 October 2012 - 04:11 AM

So I've been working on a dice rolling program for a while now and have been stuck on a problem that a friend of mine wants me to fix. The dice roller is meant for tabletop roleplaying games and so the amount of dice can be anything from 1d20 to 1000d1000.

So what would end up happening is that you enter the dice amount and the sides of the dice and then the program will tell you the results of each individual roll and the added results of all rolls.

In the case of this dice roller, it seems that rolling a big number, say 1d1000, results in a roll that says it is 16, but the total is 272. Sometimes the results of the roll will come up negative like -94 or something.

Anyone want to lend a hand on this?

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

int main()
{
    //initilization of Dice amount
    char dice[64];
    unsigned diceSides, diceAmount;
    signed modifier = 0;
    int diceTotal = 0;
    char *diceResultList;
    char *diceList;

    srand ( time (NULL) );

    //Ask user for number of sides and dice and how many dice to roll
    printf("Enter dice amount and sides (example, 1d20 or 1d20 +5): ");
    gets(dice);
    sscanf(dice, "%ud%u %i", &diceAmount, &diceSides, &modifier);

    //Allocation of memory
    diceResultList = malloc(sizeof(int)*sizeof(diceAmount));
    diceList = malloc(sizeof(char)*sizeof(diceAmount));

    //Initilization of dicePrintList to diceList to allow printing of results
    char *dicePrintList = diceList;

    //Hold will increase and when it it is greater than or equal to diceAmount, the loop ends
    for(int i = 0; i < diceAmount; i++)
    {
        int r = rand() % diceSides + 1;

        //Adds all dice results to an array
        diceResultList[i] = r;

        //By adding each instance of "r" to diceTotal, we can get a total of all numbers rolled
        diceTotal += r;
    }

    //loop to print out every number in the diceResultList array
    for(int j = 0; j < diceAmount; j++)
    {
        if(j + 1 < diceAmount)
            dicePrintList += sprintf(dicePrintList, "%d, ", diceResultList[j]);
        else
            dicePrintList += sprintf(dicePrintList, "%d", diceResultList[j]);
    }
    printf("%s\n", diceList);

    diceTotal += modifier;
    printf("\nTotal is: %d \n", diceTotal);

    getchar();
}



Is This A Good Question/Topic? 0
  • +

Replies To: [C] Allocating memory for Dice Roller

#2 sepp2k  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 2153
  • View blog
  • Posts: 3,311
  • Joined: 21-June 11

Re: [C] Allocating memory for Dice Roller

Posted 26 October 2012 - 04:34 AM

diceResultList = malloc(sizeof(int)*sizeof(diceAmount));
diceList = malloc(sizeof(char)*sizeof(diceAmount));



Look at those lines closely. I don't think they do what you want them to.
Was This Post Helpful? 1
  • +
  • -

#3 Aphex19  Icon User is offline

  • Born again Pastafarian.
  • member icon

Reputation: 615
  • View blog
  • Posts: 1,873
  • Joined: 02-August 09

Re: [C] Allocating memory for Dice Roller

Posted 26 October 2012 - 04:44 AM

Your program is leaking memory. You malloc memory to 'diceResultList' and 'diceList' and never free it. I think that would be a good place to start in bug fixing.
Was This Post Helpful? 0
  • +
  • -

#4 baavgai  Icon User is online

  • Dreaming Coder
  • member icon

Reputation: 5928
  • View blog
  • Posts: 12,851
  • Joined: 16-October 07

Re: [C] Allocating memory for Dice Roller

Posted 26 October 2012 - 05:52 AM

First, why do you need arrays? Why add stuff up into a string buffer? Given your input and output, you don't need to allocate anything.

The signed, unsigned thing isn't required, it's more distracting than anything else. Never, ever, use gets. The sscanf is good, but you should check it. Always print out the data you read in so you're sure you're working on what you think you are.

I ended up writing a version sans arrays. Hope it helps.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

void rollDice(int diceAmount, int diceSides, int modifier) {
	int i, total = modifier;

	printf("\n%dd%d", diceAmount, diceSides);
	if (modifier!=0) { printf(" %d", modifier); }
	printf(": ");
	for(i = 0; i < diceAmount; i++) {
		signed die = (rand() % diceSides) + 1;
		total += die;
		
		if (i!=0) { printf(", "); }
		printf("%d", die);
	}
	printf("\nTotal is: %d \n", total);
}

void rollDiceFromStr(const char *s) {
	int diceSides, diceAmount, modifier = 0;
	sscanf(s, "%ud%u %i", &diceAmount, &diceSides, &modifier);
	rollDice(diceAmount, diceSides, modifier);
}

void fromUserInput() {
	char dice[64];

	printf("Enter dice amount and sides (example, 1d20 or 1d20 +5): ");
	// warning: the `gets' function is dangerous and should not be used.
	// gets(dice);
	fgets(dice, sizeof(dice), stdin);
	rollDiceFromStr(dice);
}

int main() {
	srand ( time (NULL) );
	
	fromUserInput();
	return 0;
}



Always use functions. Why have three? One is your standard user input. But what if you wanted to test your string parsing? What if you just wanted to test your roller? I'd probably write this to accept command line args. Typing is tedious, but batching makes sense.
Was This Post Helpful? 0
  • +
  • -

#5 Akasen  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 41
  • Joined: 13-August 12

Re: [C] Allocating memory for Dice Roller

Posted 26 October 2012 - 06:14 AM

Thank you all for your input thus far. While I do see where you are coming from Baavgai with your take on what I'm doing, I'm currently doing this as a way to learn C and programming.

Much of what I have are the results of suggestions I'd been given from the guy assisting me and at the moment, I'm just being told what to do and what to look into and getting the program to print out results properly is currently on the to do list. How to go about this is totally up to me, so I could probably just as well show him your (baavgai) source and see how he responds to it.

As for sepp2k, all I know is that the lines allocate memory for the results. That's about it.

diceResultList = malloc(sizeof(int)*sizeof(diceAmount));
diceList = malloc(sizeof(char)*sizeof(diceAmount));


And for Aphex19, you mean like using "free()"? So I would do free(diceResultList) after declaring them or something?
Was This Post Helpful? 0
  • +
  • -

#6 baavgai  Icon User is online

  • Dreaming Coder
  • member icon

Reputation: 5928
  • View blog
  • Posts: 12,851
  • Joined: 16-October 07

Re: [C] Allocating memory for Dice Roller

Posted 26 October 2012 - 07:09 AM

View PostAkasen, on 26 October 2012 - 09:14 AM, said:

I'm currently doing this as a way to learn C and programming.


Well, all programming is about solving a problem as simply and clearly as possible.

Right, so you have to use malloc for arrays of stuffs...

Look again: diceResultList = malloc(sizeof(int)*sizeof(diceAmount));
Compare to: diceResultList = malloc(sizeof(int)*diceAmount);

See the difference? Note, your original code has diceResultList as char *.

Regardless of what you're tying to learn, using functions is vital to procedural programming. Even doing what you're doing, functions serve to isolate variable scopes and logic.

Indeed, to make your approach make more sense, you could return those result sets. e.g.

int *getDiceResultList(int diceAmount, int diceSides);
char *getResultsString(int *results, int diceAmount, int diceSides, int modifier);

void showResults(int diceAmount, int diceSides, int modifier) {
	int *resultValues = getDiceResultList(diceAmount, diceSides);
	char *resultStr = getResultsString(resultValues, diceAmount, diceSides, modifier);
	printf("%s\n", resultStr);
	free(resultValues);
	free(resultStr);
}


This post has been edited by baavgai: 26 October 2012 - 07:13 AM

Was This Post Helpful? 0
  • +
  • -

#7 Akasen  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 41
  • Joined: 13-August 12

Re: [C] Allocating memory for Dice Roller

Posted 01 November 2012 - 03:42 PM

Baavgai, I just remembered why arrays were being used. While it may have been wrong, the hypothetical idea was to develop a program for something like Skype. The idea was to then have all the results printed in one message rather than have the results be printed like crazy or not be fully printed at all.

That is where Sprintf comes from, which resulted in my previous posts in this forum that I goofed in asking, and the current task I have been given.

I do not mean to disregard your suggestions of using functions and making programs more modular. I have actually started looking into the usage of functions in other tasks I have worked on in my spare time.

I don't mean to offend, but I need an explanation in terms of the source code I have posted what can be done to make it work properly and why it works.

This post has been edited by Akasen: 01 November 2012 - 03:45 PM

Was This Post Helpful? 0
  • +
  • -

#8 jjl  Icon User is offline

  • Engineer
  • member icon

Reputation: 1112
  • View blog
  • Posts: 4,619
  • Joined: 09-June 09

Re: [C] Allocating memory for Dice Roller

Posted 01 November 2012 - 04:07 PM

Quote

Your program is leaking memory.

It's not leaking any memory. Yes he doesn't free the memory before the program finishes, but the memory is free'd regardless at that point.

    diceResultList = malloc(sizeof(int)*sizeof(diceAmount));
    diceList = malloc(sizeof(char)*sizeof(diceAmount));



diceList and diceResultList are both character points, yet for for diceResultList you allocate run time memory in a multiple of 4-byte integers. Of course a character pointer can point anywhere without a bus error, but I don't see the reasoning behind your memory allocation.

You should read up on malloc and run time memory

http://www.cplusplus...cstdlib/malloc/
Was This Post Helpful? 0
  • +
  • -

#9 Akasen  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 41
  • Joined: 13-August 12

Re: [C] Allocating memory for Dice Roller

Posted 01 November 2012 - 05:38 PM

I'm starting to lose sight of it's reasoning as well. The idea is that the amount of dice rolled would equate to how much memory needs to be allocated. So if I rolled 5 dice, 5 memory spaces would be allocated. At least I think that was what I was going for.

    diceResultList = malloc(sizeof(char)*(diceAmount));
    diceList = malloc(sizeof(char)*(diceAmount));


Looking over the code I have posted here, I made this change.
Was This Post Helpful? 0
  • +
  • -

#10 Akasen  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 41
  • Joined: 13-August 12

Re: [C] Allocating memory for Dice Roller

Posted 08 November 2012 - 05:42 PM

Okay I hate to double post, but I haven't had a response in a week. I would like to know Why the array is showing negative numbers or incorrect numbers.
Was This Post Helpful? 0
  • +
  • -

#11 Oler1s  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 1395
  • View blog
  • Posts: 3,884
  • Joined: 04-June 09

Re: [C] Allocating memory for Dice Roller

Posted 08 November 2012 - 05:49 PM

Please create a new topic (put a link back to this thread if you wish). In the new thread, post your code, input, expected output, and actual output.
Was This Post Helpful? 0
  • +
  • -

#12 Skydiver  Icon User is offline

  • Code herder
  • member icon

Reputation: 3662
  • View blog
  • Posts: 11,461
  • Joined: 05-May 12

Re: [C] Allocating memory for Dice Roller

Posted 08 November 2012 - 05:50 PM

Post your current code.

Are you sure you are accessing the correct elements of you array and that those elements were initialized. Remember that malloc() does not zero fill the memory it allocates.
Was This Post Helpful? 0
  • +
  • -

#13 Akasen  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 41
  • Joined: 13-August 12

Re: [C] Allocating memory for Dice Roller

Posted 08 November 2012 - 05:54 PM

My code looks like this at the moment
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <stdint.h>
#include <string.h>

int main()
{
    //initilization of Dice amount
    char dice[64];
    unsigned diceSides, diceAmount;
    signed modifier = 0;
    int diceTotal = 0;
    char *diceResultList;
    char *diceList;

    srand ( time (NULL) );

    free(diceList);
    free(diceResultList);

    //Ask user for number of sides and dice and how many dice to roll
    printf("Enter dice amount and sides (example, 1d20 or 1d20 +5): ");
    gets(dice);
    sscanf(dice, "%ud%u %i", &diceAmount, &diceSides, &modifier);

    //Allocation of memory
    diceResultList = malloc(sizeof(char)*(diceAmount));
    diceList = malloc(sizeof(char)*(diceAmount));

    //Initilization of dicePrintList to diceList to allow printing of results
    char *dicePrintList = diceList;

    //Hold will increase and when it it is greater than or equal to diceAmount, the loop ends
    for(int i = 0; i < diceAmount; i++)
    {
        int r = rand() % diceSides + 1;

        //Adds all dice results to an array
        diceResultList[i] = r;

        //By adding each instance of "r" to diceTotal, we can get a total of all numbers rolled
        diceTotal += r;
    }

    //loop to print out every number in the diceResultList array
    for(int j = 0; j < diceAmount; j++)
    {
        if(j + 1 < diceAmount)
            dicePrintList += sprintf(dicePrintList, "%d, ", diceResultList[j]);
        else
            dicePrintList += sprintf(dicePrintList, "%d", diceResultList[j]);
    }
    printf("%s\n", diceList);

    diceTotal += modifier;
    printf("\nTotal is: %d \n", diceTotal);

    getchar();
}


Was This Post Helpful? 0
  • +
  • -

#14 Skydiver  Icon User is offline

  • Code herder
  • member icon

Reputation: 3662
  • View blog
  • Posts: 11,461
  • Joined: 05-May 12

Re: [C] Allocating memory for Dice Roller

Posted 08 November 2012 - 05:56 PM

Yikes! On lines 19-20 you are freeing uninitialized pointers!

But the major source of your problem is the incorrect type for your diceResultList on line 14. You are trying to store int's into an array of char's on line 40. And then later you on lines 50 and 52, your are trying to pull int's out of an array of char's.

This post has been edited by Skydiver: 08 November 2012 - 05:59 PM

Was This Post Helpful? 1
  • +
  • -

#15 Akasen  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 41
  • Joined: 13-August 12

Re: [C] Allocating memory for Dice Roller

Posted 08 November 2012 - 05:58 PM

Woops, I thought I removed that line after I found it not working.

Let's try this one more time.

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

int main()
{
    //initilization of Dice amount
    char dice[64];
    unsigned diceSides, diceAmount;
    signed modifier = 0;
    int diceTotal = 0;
    char *diceResultList;
    char *diceList;

    srand ( time (NULL) );

    //Ask user for number of sides and dice and how many dice to roll
    printf("Enter dice amount and sides (example, 1d20 or 1d20 +5): ");
    gets(dice);
    sscanf(dice, "
%u %i", &diceAmount, &diceSides, &modifier);

    //Allocation of memory
    diceResultList = malloc(sizeof(double)*(diceAmount));
    diceList = malloc(sizeof(double)*(diceAmount));

    //Initilization of dicePrintList to diceList to allow printing of results
    char *dicePrintList = diceList;

    //Hold will increase and when it it is greater than or equal to diceAmount, the loop ends
    for(int i = 0; i < diceAmount; i++)
    {
        int r = rand() % diceSides + 1;

        //Adds all dice results to an array
        diceResultList[i] = r;

        //By adding each instance of "r" to diceTotal, we can get a total of all numbers rolled
        diceTotal += r;
    }

    //loop to print out every number in the diceResultList array
    for(int j = 0; j < diceAmount; j++)
    {
        if(j + 1 < diceAmount)
            dicePrintList += sprintf(dicePrintList, "%d, ", diceResultList[j]);
        else
            dicePrintList += sprintf(dicePrintList, "%d", diceResultList[j]);
    }
    printf("%s\n", diceList);

    diceTotal += modifier;
    printf("\nTotal is: %d \n", diceTotal);

    getchar();
}



This post has been edited by Akasen: 08 November 2012 - 05:59 PM

Was This Post Helpful? 0
  • +
  • -

  • (2 Pages)
  • +
  • 1
  • 2