| | |
Problem with memory allocation =(
![]() |
•
•
Join Date: Feb 2007
Posts: 10
Reputation:
Solved Threads: 0
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
The function gives me the following errors:
If i hash out the function, and simply replace the *filename code in line 7 with 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
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 =)
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
C Syntax (Toggle Plain Text)
#include <conio.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> FILE *fp; char ch, *filename (char *buf, size_t length, FILE *f); long lSize; float *buffer; int main(int argc, char *argv[]) { #define initial_value 0.07 #define increment 0.125 while (1) { // Input filename. printf("\nEnter a filename: "); gets(*filename); // Try to open the file. if ( (fp = fopen(filename, "r")) == NULL ) { perror("\nError opening file"); puts("\nEnter x to exit, any other to try again."); if ( (ch = getch()) == 'x') break; } else { // obtain file size. fseek (fp , 0 , SEEK_END); lSize = ftell (fp); rewind (fp); // allocate memory to contain the whole file. buffer = (float*)malloc(lSize); if (buffer == NULL) exit (EXIT_FAILURE); else printf("\n%d bytes of memory allocated to file...\n", lSize); printf("\nSuccessful opened %s!\n", filename); // copy the file into the buffer. // terminate fclose (fp); free (buffer); puts("\nEnter x to exit, any other to continue."); if ( (ch = getch()) == 'x') break; } } } //--------------FUNCTIONS-------------- char *filename (char *buf, size_t length, FILE *f) { char buf[40], *p; if (p = fgets (buf, length, f)) { size_t last = strlen (buf) - 1; if (buf[last] == '\n') { buf[last] = '\0'; } else { fscanf (f, "%*[^\n]"); (void) fgetc (f); } } return p; }
The function gives me the following errors:
C Syntax (Toggle Plain Text)
19: error: cannot convert `char*(*)(char*, size_t, FILE*)' to `const char*' for argument `1' to `FILE* fopen(const char*, const char*)' 57: error: declaration of 'char buf[40]' shadows a parameter :: === Build finished: 2 errors, 0 warnings ===
C Syntax (Toggle Plain Text)
filename[40];
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
C Syntax (Toggle Plain Text)
// 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 =)
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:
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
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
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
The other error "57: error: declaration of 'char buf[40]' shadows a parameter" is that
.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:
C Syntax (Toggle Plain Text)
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 •
•
Join Date: Feb 2007
Posts: 10
Reputation:
Solved Threads: 0
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
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
•
•
•
•
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
C Syntax (Toggle Plain Text)
#include <conio.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> FILE *fp; char ch, *filename (char *buf, size_t length, FILE *f); long lSize; float *buffer; int main(int argc, char *argv[]) { #define initial_value 0.07 #define increment 0.125 while (1) { // Input filename. printf("\nEnter a filename: "); gets(*filename); // Try to open the file. if ( (fp = fopen(filename, "r")) == NULL ) { perror("\nError opening file"); puts("\nEnter x to exit, any other to try again."); if ( (ch = getch()) == 'x') break; } else { // obtain file size. fseek (fp , 0 , SEEK_END); lSize = ftell (fp); rewind (fp); // allocate memory to contain the whole file. buffer = (float*)malloc(lSize); if (buffer == NULL) exit (EXIT_FAILURE); else printf("\n%d bytes of memory allocated to file...\n", lSize); printf("\nSuccessful opened %s!\n", filename); // copy the file into the buffer. // terminate fclose (fp); free (buffer); puts("\nEnter x to exit, any other to continue."); if ( (ch = getch()) == 'x') break; } } } //--------------FUNCTIONS-------------- char *filename (char *buf, size_t length, FILE *f) { char buf[40], *p; if (p = fgets (buf, length, f)) { size_t last = strlen (buf) - 1; if (buf[last] == '\n') { buf[last] = '\0'; } else { fscanf (f, "%*[^\n]"); (void) fgetc (f); } } return p; }
The function gives me the following errors:
If i hash out the function, and simply replace the *filename code in line 7 withC Syntax (Toggle Plain Text)
19: error: cannot convert `char*(*)(char*, size_t, FILE*)' to `const char*' for argument `1' to `FILE* fopen(const char*, const char*)' 57: error: declaration of 'char buf[40]' shadows a parameter :: === Build finished: 2 errors, 0 warnings ===it works fine!C Syntax (Toggle Plain Text)
filename[40];
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 underC Syntax (Toggle Plain Text)
// 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 =)
c Syntax (Toggle Plain Text)
ptr->name; /* might hold a name */ (*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 1:36 pm.
C Syntax (Toggle Plain Text)
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> #define initial_value 0.07 #define increment 0.125 int read_one_float( float* out_float, FILE *f ) ; int main(int argc, char *argv[]) { FILE *file_pointer = 0; char ch = 0; char filename[40] = "" ; long lSize = 0; float *buffer = 0; float tmp_float = 0 ; int i = 0 ; int j = 0 ; // Input filename. printf("\nEnter a filename(max 40 chars): "); gets(filename); // Try to open the file. if ( (file_pointer = fopen(filename, "r")) == NULL ) { perror("\nError opening file"); return 1 ; } printf("\nSuccessful opened %s!\n", filename); //if we reach here file is opened successfully.. //given it's an ascii file lets assume that there is //one float number per line. So total number of floats //in file is same as number of new lines + 1. // calculate the size of our buffer. while( EOF != (ch = fgetc(file_pointer)) ) if( ch == '\n' ) lSize++ ; lSize++ ; //for +1 rewind (file_pointer); // allocate memory to contain the whole file. buffer = (float*)malloc(sizeof(float)*lSize); if (buffer == NULL) return 1; else printf("\n%d bytes of memory allocated to buffer for %d entries...\n", sizeof(float)*lSize, lSize); // copy the file into the buffer. while( 0 != read_one_float( &tmp_float, file_pointer ) ) buffer[i++] = tmp_float ; //can be done like this also //while( 0 != read_one_float( &buffer[i++], file_pointer ) ) printf("\nnumber of entries read = %d", --i ) ; // terminate fclose (file_pointer); free (buffer); printf("\nData read from file is.") ; for( j = i; j >= 0; j-- ) printf("\nbuffer[%d] = %f", i-j, buffer[i-j] ) ; //we have the data in the buffer //i contains the number of entries. printf("\n\n") ; return 0 ; } //--------------FUNCTIONS-------------- int read_one_float( float* out_float, FILE *f ) { char buf[100] = "" ; if (0 == fgets(buf, 100, f)) return 0 ; *out_float = atof( buf ) ; return 1; }
•
•
•
•
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).
•
•
•
•
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
c Syntax (Toggle Plain Text)
float *float_pointer; 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:
c Syntax (Toggle Plain Text)
int i = sizeof(string);
Good luck, LamaBot
Last edited by Lazaro Claiborn; Mar 1st, 2007 at 3:09 am.
![]() |
Similar Threads
- problem with freeing memory (C)
- dynamic memory allocation (C++)
- why memory allocation (C)
- memory allocation ptr to array? how? (C)
- Why use Dynamic and Static Memory Allocation... (C)
- memory allocation (C)
- Dynamic memory allocation homework (C++)
- How to use alloc's memory allocation functions? (C)
Other Threads in the C Forum
- Previous Thread: Problems linking libs, I think...
- Next Thread: Merge Sort
| Thread Tools | Search this Thread |
* adobe ansi api array binarysearch centimeter changingto char character cm convert copyanyfile copypdffile cprogramme createcopyoffile createprocess() csyntax database directory feet fflush fgets file floatingpointvalidation fork frequency function givemetehcodez global graphics gtkgcurlcompiling gtkwinlinux highest histogram homework i/o inches infiniteloop input interest intmain() iso keyboard kilometer km linked linkedlist linux linuxsegmentationfault list locate looping lowest match meter microsoft mqqueue mysql oddnumber odf open opendocumentformat openwebfoundation owf pattern pdf performance posix power probleminc program programming pyramidusingturboccodes read recv recvblocked repetition reversing scanf scheduling segmentationfault send single socketprograming socketprogramming stack standard string suggestions systemcall unix urboc user voidmain() wab whythiscodecausesegmentationfault win32api windows.h windowsapi






