Programming Forums
User Name Password Register
 

RSS Feed
FORUM INDEX | TODAY'S POSTS | UNANSWERED THREADS | ADVANCED SEARCH

Reply
 
Thread Tools Display Modes
Old Jun 18th, 2008, 8:29 PM   #1
gj15987
Programmer
 
Join Date: Feb 2005
Posts: 45
Rep Power: 0 gj15987 is on a distinguished road
Correct use of malloc?

The exact uses of malloc and realloc are confusing me a bit. I know they need to be used when you don't know how much space you're going to need, e.g. storing a user entered string, but I'm still not 100% sure I'm using them correctly.

Is the following program ok? The original example declared an array called buffer, of size 20, and printed an error if the output string was longer than 20. So I decided to use malloc so that any size string could be output. At the start I used malloc to allocate enough space for 1 char, and then on each successive loop I used realloc to allocate space for another char.

The program basically converts a given decimal number, into the base given. The function hexDigit(int n) converts 10 to A, 11 to B etc if the given base is base 16.

Thanks in advance.

c Syntax (Toggle Plain Text)
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. char hexDigit(int n) {
  5. return (n < 10)?(n + 48):(n + 55);
  6. }
  7.  
  8. void baseConv(int n, int b) {
  9. if (b < 2 || b > 16) {
  10. printf("Base out of range!");
  11. return;
  12. } else {
  13. char *buffer;
  14. int i = -1;
  15. while (n >= b) {
  16. i++;
  17. // First time round use malloc
  18. if (i == 0) {
  19. buffer = (char *) malloc(sizeof(char));
  20. } else {
  21. buffer = (char *) realloc(buffer, sizeof(buffer) + sizeof(char));
  22. }
  23. buffer[i] = hexDigit(n % b);
  24. n = n/b;
  25. }
  26. printf("%c", hexDigit(n));
  27. while (i > -1) {
  28. printf("%c", buffer[i]);
  29. i--;
  30. }
  31. free(buffer);
  32. }
  33. }
  34.  
  35. int main() {
  36. baseConv(123123123,2); // Just a tester
  37. printf("\n");
  38. return 0;
  39. }

EDIT: I also don't understand examples like this: http://www.captain.at/howto-c-code-malloc-struct.php

Why is malloc needed to allocate memory to those structs? They don't have any character pointers so I don't see why malloc is needed.
gj15987 is offline   Reply With Quote
Old Jun 18th, 2008, 9:43 PM   #2
The Dark
Expert Programmer
 
Join Date: Jun 2005
Posts: 825
Rep Power: 4 The Dark is on a distinguished road
Re: Correct use of malloc?

This code
buffer = (char *) realloc(buffer, sizeof(buffer) + sizeof(char));
won't work, because sizeof(buffer) is the size of the buffer pointer, not the size of the memory that is allocated. Another way of looking at it is that sizeof(buffer) is sizeof(char *) which is 4 on a 32 bit system (more or less on other systems).

Instead of using sizeof(buffer), you could use the counter you already have (i), you are about to assign into buffer[i], so buffer needs to be at least i+1 in size. so you could use
buffer = (char *) realloc(buffer, (i + 1) * sizeof(char));

Note that reallocating your buffer each time round the loop is probably not the most efficient way of doing things. Another way would be to allocate a reasonable sized buffer initially (say 20 bytes), and then increase it if you need to (e.g. if i becomes 20). This may make your code a bit more complicated, and isn't really necessary for a program of this size - you won't notice any difference in speed.
The Dark is offline   Reply With Quote
Old Jun 19th, 2008, 1:53 AM   #3
mbd
Programmer
 
Join Date: Nov 2007
Posts: 86
Rep Power: 1 mbd is on a distinguished road
Re: Correct use of malloc?

what is anyone's opinion of
c Syntax (Toggle Plain Text)
  1. char *s = calloc(10, sizeof(char));
vs
c Syntax (Toggle Plain Text)
  1. char *s = calloc(10, sizeof(*s));
mbd is offline   Reply With Quote
Old Jun 19th, 2008, 2:50 AM   #4
gj15987
Programmer
 
Join Date: Feb 2005
Posts: 45
Rep Power: 0 gj15987 is on a distinguished road
Re: Correct use of malloc?

Thank you The Dark.

For anyone else who may have run into similar problems in the past, I found the following method is good for checking that enough memory has been allocated. Every time you malloc or realloc, put printf("Memory is now: %d bytes\n", <allocated memory here>); That way you can double check the right amount of memory is being allocated.

Quote:
Originally Posted by mbd View Post
what is anyone's opinion of
c Syntax (Toggle Plain Text)
  1. char *s = calloc(10, sizeof(char));
vs
c Syntax (Toggle Plain Text)
  1. char *s = calloc(10, sizeof(*s));
I suppose either work just as well. I'd use the first one just because it's easy to remember that char is a char, and I don't have to check what *s points to.
gj15987 is offline   Reply With Quote
Old Jun 20th, 2008, 5:36 AM   #5
gj15987
Programmer
 
Join Date: Feb 2005
Posts: 45
Rep Power: 0 gj15987 is on a distinguished road
Re: Correct use of malloc?

I have now edited my program so that it uses a buffer of 5 chars, and when the buffer gets full, it malloc/reallocs memory to store the buffer so far and then starts filling the buffer from the start again.

If anyone has any time, could they verify that I am using malloc/realloc properly and also freeing all the memory (i.e. no memory leaks)?

Thanks a lot.
c Syntax (Toggle Plain Text)
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4.  
  5. char hexDigit(int n) {
  6. return (n < 10)?(n + 48):(n + 55);
  7. }
  8.  
  9. #define BUFFER 5
  10.  
  11. void baseConv(int n, int b) {
  12. char *line = NULL, *dest, buffer[BUFFER];
  13. int i = 0; // Finished flag
  14.  
  15. while (n >= b) {
  16. if (i == 5) { // If buffer is full
  17. // malloc some space to line
  18. if (line == NULL) { // First time round line will be null
  19. line = (char *) malloc(sizeof(buffer));
  20. dest = line; // Point dest to start of line
  21. } else { // line already has something in it
  22. line = (char *) realloc(line, sizeof(buffer) + (dest - line));
  23. }
  24. // Now add buffer to line, starting at dest
  25. for (i = 0; i < 5; i++) {
  26. *dest = buffer[i];
  27. dest++;
  28. }
  29. i = 0; // Rest i
  30. } else { // Buffer is not full, add char to it
  31. buffer[i] = hexDigit(n % b);
  32. n = n/b;
  33. i++;
  34. }
  35. }
  36.  
  37. // Print out remaining n
  38. printf("%c", hexDigit(n));
  39. // Print out what's left in buffer
  40. while (--i > -1) {
  41. printf("%c", buffer[i]);
  42. }
  43.  
  44. if (line != NULL) { // If line was used (number was longer than buffer)
  45. // Print out line
  46. while (--dest >= line) {
  47. printf("%c",*dest);
  48. }
  49. free(line);
  50. }
  51. }
  52.  
  53. int main() {
  54. int num, base;
  55. printf("Please enter a whole number: ");
  56. scanf("%d",&num);
  57. printf("Please enter a base (2, 8 or 16): ");
  58. scanf("%d",&base);
  59. printf("Your number %d in base %d is: ", num, base);
  60. baseConv(num,base);
  61. printf("\n");
  62. return 0;
  63. }
gj15987 is offline   Reply With Quote
Old Jun 21st, 2008, 9:36 PM   #6
The Dark
Expert Programmer
 
Join Date: Jun 2005
Posts: 825
Rep Power: 4 The Dark is on a distinguished road
Re: Correct use of malloc?

One problem I can see is that the realloc call might change the location of the allocated memory - it does this if it can't grow the memory in-place.
This will mean that your "dest" variable now doesn't point to allocated memory any more. You will need to point dest back to the appropriate spot in the new "line" variable.

The other problem is that the memory management part is very complicated, and overshadows the actual calculations. Unless you have extreme memory limitations, or if you are just practising with mallocs etc, I'd suggest simplifying it. If you want to simplify it, you could work out your biggest buffer requirement for any value, and just set your buffer size to that. If you don't mind assuming an 8 bit byte, you can use sizeof(int) to work out the number of bytes in an int and then multiply that by 8, that should give you the length of the biggest binary number you are likely to encounter. Then just allocate that on the stack.
The Dark is offline   Reply With Quote
Old Jun 23rd, 2008, 10:29 AM   #7
Narue
Professional Programmer
 
Narue's Avatar
 
Join Date: Sep 2005
Posts: 419
Rep Power: 3 Narue is on a distinguished road
Re: Correct use of malloc?

Quote:
Originally Posted by mbd View Post
what is anyone's opinion of
c Syntax (Toggle Plain Text)
  1. char *s = calloc(10, sizeof(char));
vs
c Syntax (Toggle Plain Text)
  1. char *s = calloc(10, sizeof(*s));
The latter is easier to maintain because it limits the number of places you have to change the type. char in particular is problematic because a lot of code that assumes ASCII is being updated to support Unicode. It's very easy to do this by accident:
c Syntax (Toggle Plain Text)
  1. utf16_t *s = calloc(10, sizeof(char));
Or in a more realistic scenario:
c Syntax (Toggle Plain Text)
  1. utf16_t *s = calloc(10, sizeof(utf16_6));
  2.  
  3. /* A lot of code */
  4.  
  5. s = realloc(s, size * sizeof(char));
  6.  
  7. /*
  8.   Even worse, but more likely, alternative
  9.   s = realloc(s, size);
  10. */
Automated replacements tend not to catch that bug.

>I'd use the first one just because it's easy to remember that
>char is a char, and I don't have to check what *s points to.
It's difficult to look slightly to the left? Your reason makes more sense when the statement isn't a declaration for s. However, I would claim that if you have no clue what the type of *s is and you need to know, your problems are more than stylistic.

I honestly can't think of a place where I would need to know the type and can't easily figure it out without introducing a maintenance problem.
__________________
Even if the voices aren't real, they have some pretty good ideas.
Narue is offline   Reply With Quote
Reply

Bookmarks

« Previous Thread in Forum | Next Thread in Forum »

Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
A Malloc question metsfan C 3 Apr 20th, 2006 11:37 AM
Question regarding Malloc() and Type casting sparda C 6 Sep 29th, 2005 4:12 AM
malloc and new brkstf C++ 6 Apr 21st, 2005 11:03 AM
how to use malloc() and free() FarAway C++ 5 Feb 16th, 2005 11:08 AM
C++ programmer needs some info on malloc() uman C++ 2 Jan 25th, 2005 7:10 PM




DaniWeb IT Discussion Community
All times are GMT -5. The time now is 4:45 PM.

Powered by vBulletin® Version 3.7.0, Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Copyright ©2007 DaniWeb® LLC