User Name Password Register
DaniWeb IT Discussion Community
All
What is DaniWeb IT Discussion Community?
You're currently browsing the C section within the Software Development category of DaniWeb, a massive community of 426,182 software developers, web developers, Internet marketers, and tech gurus who are all enthusiastic about making contacts, networking, and learning from each other. In fact, there are 1,794 IT professionals currently interacting right now! Registration is free, only takes a minute and lets you enjoy all of the interactive features of the site.
Please support our C advertiser: Programming Forums
Views: 1476 | Replies: 13
Reply
Join Date: Feb 2007
Posts: 10
Reputation: MiloTN is an unknown quantity at this point 
Rep Power: 2
Solved Threads: 0
MiloTN MiloTN is offline Offline
Newbie Poster

Help Problem with memory allocation =(

  #1  
Feb 28th, 2007
Hi there^^ Its my first post on these forums, and as much as I hate it to be a shout for help ive got a problem I could really use someone with a bit of knowledge to help me out with =)

My scenario being ive got to write a code that asks the user for input from a file (in this particular case it will be a number of folat values in .txt format), scan them into an array, and manipulate said array with a few mathematical functions, and whack it through a final calculation to give a value output to the screen.

Right now ive spent days and days trying to code the first part correctly, and its kicking my ass (Im new to any form of programming!). I could make it more basic by defining the array size, but I actually find all this quite interesting, so id rather learn the hard way :cheesy:


Anyway, without further ado, here's what ive got so far, and no, it doesnt work =P

  1. #include <conio.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <errno.h>
  6. FILE *fp;
  7. char ch, *filename (char *buf, size_t length, FILE *f);
  8. long lSize;
  9. float *buffer;
  10.  
  11. int main(int argc, char *argv[])
  12. {
  13. #define initial_value 0.07
  14. #define increment 0.125
  15. while (1)
  16. {
  17. // Input filename.
  18. printf("\nEnter a filename: ");
  19. gets(*filename);
  20. // Try to open the file.
  21. if ( (fp = fopen(filename, "r")) == NULL )
  22. {
  23. perror("\nError opening file");
  24. puts("\nEnter x to exit, any other to try again.");
  25. if ( (ch = getch()) == 'x')
  26. break;
  27. }
  28. else
  29. {
  30. // obtain file size.
  31. fseek (fp , 0 , SEEK_END);
  32. lSize = ftell (fp);
  33. rewind (fp);
  34. // allocate memory to contain the whole file.
  35. buffer = (float*)malloc(lSize);
  36. if (buffer == NULL) exit (EXIT_FAILURE);
  37. else printf("\n%d bytes of memory allocated to file...\n", lSize);
  38. printf("\nSuccessful opened %s!\n", filename);
  39.  
  40. // copy the file into the buffer.
  41.  
  42.  
  43. // terminate
  44. fclose (fp);
  45. free (buffer);
  46. puts("\nEnter x to exit, any other to continue.");
  47. if ( (ch = getch()) == 'x')
  48. break;
  49. }
  50.  
  51. }
  52. }
  53. //--------------FUNCTIONS--------------
  54.  
  55. char *filename (char *buf, size_t length, FILE *f)
  56. {
  57. char buf[40], *p;
  58. if (p = fgets (buf, length, f))
  59. {
  60. size_t last = strlen (buf) - 1;
  61. if (buf[last] == '\n') {
  62. buf[last] = '\0';
  63. }
  64. else {
  65. fscanf (f, "%*[^\n]");
  66. (void) fgetc (f);
  67. }
  68. }
  69. return p;
  70. }

The function gives me the following errors:

  1. 19: error: cannot convert `char*(*)(char*, size_t, FILE*)' to `const char*' for argument `1' to `FILE* fopen(const char*, const char*)'
  2. 57: error: declaration of 'char buf[40]' shadows a parameter
  3. :: === Build finished: 2 errors, 0 warnings ===
If i hash out the function, and simply replace the *filename code in line 7 with
  1. filename[40];
it works fine!

Also, I cant tell if the code for buffer is working or not, it seems to be, but im too new to all this to tell, until i write the file into an array (which I cant do yet since I do not know how do define an array size for a file that can be of different sizes...)

The code for the array will go in the middle of the program, where ive left room for it under
  1. // copy the file into the buffer.



Im sorry, that was a real mouthful, any help would be greatly appreciated ^^

Chris

edit: you can ignore the define's for now, theyre to be used in the calculations later on =)
AddThis Social Bookmark Button
Reply With Quote  
Join Date: Feb 2007
Location: Bangalore, India
Posts: 535
Reputation: thekashyap will become famous soon enough thekashyap will become famous soon enough 
Rep Power: 4
Solved Threads: 50
thekashyap's Avatar
thekashyap thekashyap is offline Offline
Posting Pro

Re: Problem with memory allocation =(

  #2  
Feb 28th, 2007
First of all, let me say that if you're new to programming you've done a great job with 'neatness' of code. It's so nice to see code with comments. .
Anyway..
A few questions I have before I can answer..
1. Is it mandatory for u to use C? Can't u use C++? It would a LOT easier with C++ STL n all..
2. Is you file an ascii file or a binary/data file? May not be related to your problem but see http://bama.ua.edu/cgi-bin/man-cgi?fopen+3C. Ideally you should opne with "rb" as the mode. (could run into to unwanted problem otherwise depending on environment, i.e. unix/windows..)


Now to the code, a few things I think you can correct.
Line 7:
  1. char ch, *filename (char *buf, size_t length, FILE *f);

It seems to me like compiler is not cribbing at line 7 itself (although it should), only because it thinks that you have correctly declared
1. char ch; = ch as a character
2. char *filename (char *buf, size_t length, FILE *f); = prototype/declaration for a function named "filename" (which is defined on line 55).
Function names are nothing but variables of type "function pointers". So when you use this function as an argument to gets() on line #19 compiler tries to match the expected type (char*) and supplied type (char*(*)(char*, size_t, FILE*)). As they don't match compiler tries to convert supplied type to the expected type using built-in (and user-defined, viz not applicable in your case) conversion operators/rules. In this case a pointer to function pointer can't be converted to char* so compiler gives an error.

When you change filename's declaration to filename[40]. Compiler sees "filename" as a "char*" which is exactly what is required by gets().

So first thing you can correct is: declare filename as char filename[40].

Second problem with the code is that you have opened the file in text /ascii mode and you are allocating teh buffer (into which you plan to read the data) as if the file is a binary/data file. The way data is stored in binary/data file is different than an ascii file (See http://www.learn-programming.za.net/...c_learn10.html)
. In simple words if your file is a binary/data file then sizeof buffer to be allocated would be same as size of file (or number of bytes ni file). But if file is an ascii file that is not true. (if a single number say 1000 is stored in an ascii file file size would be 4 bytes, if it's stored in a binary file it'll be sizeof(int)).

Third and biggest problem is you have a function AND a variable with same name (after you make the suggested correction) ! This is NEVER a good idea. Remember the rule of thumb "Never use/introduce/declare same name twice in same scope." Name here refers to a variable/function/struct-type...
So pick any one naming notation/convention of you choice and follow it. E.g. hungarian is a famous one. If you are not comfortable with that at least think of a story like name for your variables for they dn't clash. E.g. change char filename[40] to char input_filename[40].
The other error "57: error: declaration of 'char buf[40]' shadows a parameter" is that char buf[40] declared on line 57 hides the other variable in same scope which is teh function argument char *filename (char *buf, size_t length, FILE *f). May be you can change line 57 to char* tmp_buf
Reply With Quote  
Join Date: Feb 2007
Posts: 10
Reputation: MiloTN is an unknown quantity at this point 
Rep Power: 2
Solved Threads: 0
MiloTN MiloTN is offline Offline
Newbie Poster

Re: Problem with memory allocation =(

  #3  
Feb 28th, 2007
Hey there, thanks a lot for the reply and initial suggestions, ill get on it as soon as I can and post up an appended version!

To answer you're initial few questions, i have to use C I wish I could use C++, since it seems to bemuch better for dynamic memory allocation ><

Secondly, the program has to read text not binary (which explains a poblem you touched on later in your reply^^)

Be back in a bit *open up compiler* x_x

Chris
Reply With Quote  
Join Date: Jan 2007
Posts: 166
Reputation: Lazaro Claiborn is an unknown quantity at this point 
Rep Power: 2
Solved Threads: 13
Lazaro Claiborn's Avatar
Lazaro Claiborn Lazaro Claiborn is offline Offline
Junior Poster

Re: Problem with memory allocation =(

  #4  
Feb 28th, 2007
Originally Posted by MiloTN View Post
Hi there^^ Its my first post on these forums, and as much as I hate it to be a shout for help ive got a problem I could really use someone with a bit of knowledge to help me out with =)

My scenario being ive got to write a code that asks the user for input from a file (in this particular case it will be a number of folat values in .txt format), scan them into an array, and manipulate said array with a few mathematical functions, and whack it through a final calculation to give a value output to the screen.

Right now ive spent days and days trying to code the first part correctly, and its kicking my ass (Im new to any form of programming!). I could make it more basic by defining the array size, but I actually find all this quite interesting, so id rather learn the hard way :cheesy:


Anyway, without further ado, here's what ive got so far, and no, it doesnt work =P

  1. #include <conio.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <errno.h>
  6. FILE *fp;
  7. char ch, *filename (char *buf, size_t length, FILE *f);
  8. long lSize;
  9. float *buffer;
  10.  
  11. int main(int argc, char *argv[])
  12. {
  13. #define initial_value 0.07
  14. #define increment 0.125
  15. while (1)
  16. {
  17. // Input filename.
  18. printf("\nEnter a filename: ");
  19. gets(*filename);
  20. // Try to open the file.
  21. if ( (fp = fopen(filename, "r")) == NULL )
  22. {
  23. perror("\nError opening file");
  24. puts("\nEnter x to exit, any other to try again.");
  25. if ( (ch = getch()) == 'x')
  26. break;
  27. }
  28. else
  29. {
  30. // obtain file size.
  31. fseek (fp , 0 , SEEK_END);
  32. lSize = ftell (fp);
  33. rewind (fp);
  34. // allocate memory to contain the whole file.
  35. buffer = (float*)malloc(lSize);
  36. if (buffer == NULL) exit (EXIT_FAILURE);
  37. else printf("\n%d bytes of memory allocated to file...\n", lSize);
  38. printf("\nSuccessful opened %s!\n", filename);
  39.  
  40. // copy the file into the buffer.
  41.  
  42.  
  43. // terminate
  44. fclose (fp);
  45. free (buffer);
  46. puts("\nEnter x to exit, any other to continue.");
  47. if ( (ch = getch()) == 'x')
  48. break;
  49. }
  50.  
  51. }
  52. }
  53. //--------------FUNCTIONS--------------
  54.  
  55. char *filename (char *buf, size_t length, FILE *f)
  56. {
  57. char buf[40], *p;
  58. if (p = fgets (buf, length, f))
  59. {
  60. size_t last = strlen (buf) - 1;
  61. if (buf[last] == '\n') {
  62. buf[last] = '\0';
  63. }
  64. else {
  65. fscanf (f, "%*[^\n]");
  66. (void) fgetc (f);
  67. }
  68. }
  69. return p;
  70. }

The function gives me the following errors:

  1. 19: error: cannot convert `char*(*)(char*, size_t, FILE*)' to `const char*' for argument `1' to `FILE* fopen(const char*, const char*)'
  2. 57: error: declaration of 'char buf[40]' shadows a parameter
  3. :: === Build finished: 2 errors, 0 warnings ===
If i hash out the function, and simply replace the *filename code in line 7 with
  1. filename[40];
it works fine!

Also, I cant tell if the code for buffer is working or not, it seems to be, but im too new to all this to tell, until i write the file into an array (which I cant do yet since I do not know how do define an array size for a file that can be of different sizes...)

The code for the array will go in the middle of the program, where ive left room for it under
  1. // copy the file into the buffer.



Im sorry, that was a real mouthful, any help would be greatly appreciated ^^

Chris

edit: you can ignore the define's for now, theyre to be used in the calculations later on =)


The gets function takes a char pointer. When you use (*filename) you're actually passing the value stored at the address pointed to by filename, instead of passing the address stored in filename. All subsequent actions in gets using the address whose value is not a pointer will cause compiler problems. Example; say if ptr is a pointer variable to a structure, you can use either of these:

  1. ptr->name; /* might hold a name */
  2. (*ptr).name; /* same as above */

Also, I think it is better formatting if you place your #define constants after the #includes.

Good luck, LamaBot
Last edited by Lazaro Claiborn : Feb 28th, 2007 at 12:36 pm.
Reply With Quote  
Join Date: Aug 2005
Posts: 4,782
Reputation: iamthwee is a glorious beacon of light iamthwee is a glorious beacon of light iamthwee is a glorious beacon of light iamthwee is a glorious beacon of light iamthwee is a glorious beacon of light 
Rep Power: 17
Solved Threads: 319
iamthwee's Avatar
iamthwee iamthwee is offline Offline
Industrious Poster

Re: Problem with memory allocation =(

  #5  
Feb 28th, 2007
To answer you're initial few questions, i have to use C I wish I could use C++, since it seems to be much better for dynamic memory allocation

Better no, easier perhaps...
I'm not a programmer. My attitude starts with ignorance, holds steady at conversation, and ends with a trip to the hospital. Get used to it.
Reply With Quote  
Join Date: May 2006
Location: Bellevue, WA
Posts: 1,548
Reputation: Infarction has a spectacular aura about Infarction has a spectacular aura about Infarction has a spectacular aura about 
Rep Power: 8
Solved Threads: 51
Sponsor
Infarction's Avatar
Infarction Infarction is offline Offline
Battle Programmer

Re: Problem with memory allocation =(

  #6  
Feb 28th, 2007
Originally Posted by iamthwee View Post
Better no, easier perhaps...

Are you saying that it's worse, or that easier isn't better?
Reply With Quote  
Join Date: Feb 2007
Posts: 10
Reputation: MiloTN is an unknown quantity at this point 
Rep Power: 2
Solved Threads: 0
MiloTN MiloTN is offline Offline
Newbie Poster

Re: Problem with memory allocation =(

  #7  
Feb 28th, 2007
This pointer business has got me really confused

Is the general consensus that I cannot feasibly accomplish dynamiclly allocating a string size (see: my attempt at a function at the end of the program)?

Chris
Reply With Quote  
Join Date: Feb 2007
Location: Bangalore, India
Posts: 535
Reputation: thekashyap will become famous soon enough thekashyap will become famous soon enough 
Rep Power: 4
Solved Threads: 50
thekashyap's Avatar
thekashyap thekashyap is offline Offline
Posting Pro

Re: Problem with memory allocation =(

  #8  
Mar 1st, 2007
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <errno.h>
  5. #define initial_value 0.07
  6. #define increment 0.125
  7.  
  8. int read_one_float( float* out_float, FILE *f ) ;
  9.  
  10. int main(int argc, char *argv[])
  11. {
  12. FILE *file_pointer = 0;
  13. char ch = 0;
  14. char filename[40] = "" ;
  15. long lSize = 0;
  16. float *buffer = 0;
  17. float tmp_float = 0 ;
  18. int i = 0 ;
  19. int j = 0 ;
  20.  
  21. // Input filename.
  22. printf("\nEnter a filename(max 40 chars): ");
  23. gets(filename);
  24. // Try to open the file.
  25. if ( (file_pointer = fopen(filename, "r")) == NULL )
  26. {
  27. perror("\nError opening file");
  28. return 1 ;
  29. }
  30.  
  31. printf("\nSuccessful opened %s!\n", filename);
  32. //if we reach here file is opened successfully..
  33.  
  34. //given it's an ascii file lets assume that there is
  35. //one float number per line. So total number of floats
  36. //in file is same as number of new lines + 1.
  37. // calculate the size of our buffer.
  38. while( EOF != (ch = fgetc(file_pointer)) )
  39. if( ch == '\n' )
  40. lSize++ ;
  41.  
  42. lSize++ ; //for +1
  43.  
  44. rewind (file_pointer);
  45. // allocate memory to contain the whole file.
  46. buffer = (float*)malloc(sizeof(float)*lSize);
  47. if (buffer == NULL) return 1;
  48. else printf("\n%d bytes of memory allocated to buffer for %d entries...\n", sizeof(float)*lSize, lSize);
  49.  
  50. // copy the file into the buffer.
  51. while( 0 != read_one_float( &tmp_float, file_pointer ) )
  52. buffer[i++] = tmp_float ;
  53.  
  54. //can be done like this also
  55. //while( 0 != read_one_float( &buffer[i++], file_pointer ) )
  56.  
  57. printf("\nnumber of entries read = %d", --i ) ;
  58.  
  59. // terminate
  60. fclose (file_pointer);
  61. free (buffer);
  62.  
  63. printf("\nData read from file is.") ;
  64. for( j = i; j >= 0; j-- )
  65. printf("\nbuffer[%d] = %f", i-j, buffer[i-j] ) ;
  66.  
  67. //we have the data in the buffer
  68. //i contains the number of entries.
  69.  
  70. printf("\n\n") ;
  71.  
  72. return 0 ;
  73. }
  74.  
  75. //--------------FUNCTIONS--------------
  76. int read_one_float( float* out_float, FILE *f )
  77. {
  78. char buf[100] = "" ;
  79.  
  80. if (0 == fgets(buf, 100, f))
  81. return 0 ;
  82.  
  83. *out_float = atof( buf ) ;
  84.  
  85. return 1;
  86. }
Reply With Quote  
Join Date: Feb 2007
Location: Bangalore, India
Posts: 535
Reputation: thekashyap will become famous soon enough thekashyap will become famous soon enough 
Rep Power: 4
Solved Threads: 50
thekashyap's Avatar
thekashyap thekashyap is offline Offline
Posting Pro

Re: Problem with memory allocation =(

  #9  
Mar 1st, 2007
Originally Posted by MiloTN View Post
This pointer business has got me really confused

Is the general consensus that I cannot feasibly accomplish dynamiclly allocating a string size (see: my attempt at a function at the end of the program)?

Chris



Almost everything you can do in C++, can be done in C, so it's not true that dynamic allocation is not feasible.
One can say it's easier in C++ but it can be done in C as well.

Problem with the code I posted is that it assumes input file's format is like this:
----------------
float1
float2
...
floatN
----------------
If the file format is different the function read_one_float() needs to be adapted appropriately.
Also it would then be difficult to determine lSize.
E.g. assume this to be the format of file
----------------
float1,float2,...,floatN
----------------
OR even worse
----------------
float11,float12,float13,...,float1M
float21,float22,float23,...,float2M
...
floatN1,floatN2,floatN3,...,floatNM
----------------
In these cases one can't assume that number of '\n' is number of floats.
In all these cases using a linked list to hold the data would be better than using a float array.

In C++ you'll find lotsa nice containers to do this dynamic re-sizing of containers, that's why I said it's a lot easier (no matter what other say, that's the truth).
Reply With Quote  
Join Date: Jan 2007
Posts: 166
Reputation: Lazaro Claiborn is an unknown quantity at this point 
Rep Power: 2
Solved Threads: 13
Lazaro Claiborn's Avatar
Lazaro Claiborn Lazaro Claiborn is offline Offline
Junior Poster

Re: Problem with memory allocation =(

  #10  
Mar 1st, 2007
Originally Posted by MiloTN View Post
This pointer business has got me really confused

Is the general consensus that I cannot feasibly accomplish dynamiclly allocating a string size (see: my attempt at a function at the end of the program)?

Chris


It is commonly hard for a newbe to understand how pointers work. But it really isn't. Every variable has an address(s) and value(s), pointers are just variables that hold the address of another variable of the same type as the pointer. Dynamically allocating memory, you use malloc which takes the number of bytes to reserve and returns a point to this block of reserved memory. Remember that pointer of type int can only pointer to (hold the address of) a variable of type int. You cast the pointer returned by malloc to a pointer of type float; Example;

  1. float *float_pointer;
  2.  
  3. float_pointer = (float *)malloc(sizeof(float));

Anyway, don't get intimidated by the concept of pointers, just read up more about them. Also, the sizeof function can be used to determine the size of a string, like this:

  1. int i = sizeof(string);

Good luck, LamaBot
Last edited by Lazaro Claiborn : Mar 1st, 2007 at 2:09 am.
Reply With Quote  
Reply

Only community members can participate in forum threads. You must register or log in to contribute.

DaniWeb C Marketplace
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)

 

Thread Tools Display Modes

Similar Threads
Other Threads in the C Forum

All times are GMT -4. The time now is 6:32 am.
Forum system based on vBulletin Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
©2003 - 2008 DaniWeb® LLC