# Thread: Scope of memory allocation

1. ## Scope of memory allocation

I am writing a function to convert a number of any base up to 16 to a string. Here's what I have so far:

Code:
```char * IntToString(int number, int base)
{

int     i = 0;
char *  charArray;
int     digits;

// Base 16 is the maximum I decided to allow, but even "as is" this function could support higher numbers
if(base < 2 || base > 16)
return (char *) 0;

//Determine the memory required to hold the string
while(number)
{

number /= base;
i++;

}

//Save i as the total digits the number will take
digits = i;

//Allocate memory for the string
if(!(charArray = (char *) malloc(i + 1)))
return (char *) 0;

//Put each digit of the number in it's own array position
for(i; i >= 0; i--)
{

charArray[i] = number % base;
number /= base;

if(!(number))
break;

}

//Now convert the digits to their correct ASCII values
for(i = 0; i <= digits; i++)
{

if(charArray[i] < 10)
charArray[i] += 48;
else
charArray[i] += 55;

}

//Terminate the string
charArray[digits + 1] = '\0';

return charArray;

}```
The only problem is (well let's not say only since I haven't finished testing the rest of the code...) that when I use malloc within a function then the memory gets freed once the function exits, or at least that's what I think is happening. In case you are wondering, yes I'm aware of the consequences of not following this up with a call to free() later on if this wasn't the case . Anyway, I could put the code to determine the how many digits a number takes in a seporate function and allocate the memory within the scope it will be used in, but I think this method makes for neater code so I'd like to get it working if possible. All I need is a function that allocates memory in a way so that it will not get deallocated unless I explicitly say it should be. Anyone know of one? I'm writing this code for a windows based program if it makes a difference. Also, if you happen to notice any other bugs in this feel free to point them out .

Mod edit: changed php tags to code tags

2. I see a lot potential problems here but I'll point out a few things to you first.

First and foremost:

Code:
`charArray[digits + 1] = ';`
Probably meant new line character per your comment '\n'.

When you are finding out how many digits there are you are modifying the original number then later you try to use it and it is 0. Just use a temporary variable for determing number of digits so you don't modify the original. You can use the logarithm function to help you get number of digits easily if you want.

This should push you in the right direction, just step through it in the debugger and you'll spot some errors there. Let me know if you get stuck again.

3. Your corruption problem is due to the fact that you destroy number when finding the number of digits and then try to use it again to build your string. Then you have a multitude of off-by-one errors in your indexing, but you can find those when you save a copy of number to work with after finding digits.

I like the avatar. "Love and peace! Love and peace!"

4. Originally posted by MrWizard
I see a lot potential problems here but I'll point out a few things to you first.

First and foremost:

Code:
`charArray[digits + 1] = ';`
Probably meant new line character per your comment '\n'.

Well actually I meant \0 but that was in my original code. PHP formatting must've done something to it.

Originally posted by MrWizard
When you are finding out how many digits there are you are modifying the original number then later you try to use it and it is 0. Just use a temporary variable for determing number of digits so you don't modify the original. You can use the logarithm function to help you get number of digits easily if you want.
Yea, can't believe I missed that. I was just assuming I had messed up the memory handling somehow so I wasn't looking for that kind of thing that carefully

Originally posted by MrWizard
This should push you in the right direction, just step through it in the debugger and you'll spot some errors there. Let me know if you get stuck again.
Well for once thing, if the scope of the memory allocation wasn't an issue then why does using free() at the address of the memory result in a memory damage error in Visual C++?

5. Originally posted by Prelude
Your corruption problem is due to the fact that you destroy number when finding the number of digits and then try to use it again to build your string. Then you have a multitude of off-by-one errors in your indexing, but you can find those when you save a copy of number to work with after finding digits.

I like the avatar. "Love and peace! Love and peace!"
Yea, off-by-one errors are often my downfall. Oh and I'm glad to see there are other anime fans on this board .

6. '\n', doh , yea I meant \0 too, hah.

Using free on the memory you allocated shouldn't give you any problems unlessed you messed up somewhere along the way. Watch out for invalid indexing as Prelude was mentioning. Just get your algorithm working first then worry about freeing the memory, that's not the most important thing at the moment.

7. Ok here is fully working code (not gurenteed though ), now with support for negative numbers. Anyone is free to use it who finds it useful (although for all I know someone has probobly allready written better code to do the same thing.) Thanks for the help. Any additional improvements or suggestions for my code would be appreciated if you can find something that looks like it could use improving.

Code:
```char * IntToString(int number, int base)
{

int     i = 0;
BOOL    sign = 0;
char *  charArray;
int     digits;
int     tempNum;

// Base 16 is the maximum I decided to allow, but even "as is" this function could support higher numbers
if(base < 2 || base > 16)
return (char *) 0;

// Determine if the number is negative

if (number < 0)
{

sign = 1;
number = -number;

}
// Determine the memory required to hold the string

tempNum = number;

while(tempNum)
{

tempNum /= base;
i++;

}

// Save i as the total digits the number will take to store
digits = i;

// Allocate memory for the string
if(!(charArray = (char *) malloc(digits + 1 + sign)))
return (char *) 0;

//Insert a dash if the number is negative
if(sign)
charArray[0] = 45;

// Put each digit of the number in it's own array position
for(i -= !(sign); i >= sign; i--)
{

charArray[i] = number % base;
number /= base;

if(!(number))
break;

}

// Now convert the digits to their correct ASCII values
for(i = sign; i <= digits; i++)
{

if(charArray[i] < 10)
charArray[i] += 48;
else
charArray[i] += 55;

}

// Terminate the string
charArray[digits + sign] = '\0';

return charArray;

}```

8. Your function doesn't convert 0 too well. For example:
p = IntToString(0, 10);
gives an empty string (one byte containing the \0). I would expect it to contain a 0 character.

You shouldn't be using magic numbers in your code, like you do here:
charArray[0] = 45;
Instead, you character constants, like so:
charArray[0] = '-';
It's more portable, and much easier to read.

Your use of malloc() gives me two concerns:
First: http://faq.cprogramming.com/cgi-bin/...&id=1043284351
Second: you're relying on the caller to free the memory. A better way, imho, would be to accept a char pointer and length indicator as function parameters, and write to those instead. That way the caller can decide where they want the string written to, and they are fully aware if it's dynamic memory or not.