How to dynamically allocate memory for char** in C
Solution 1
Do like this:
char** list;
list = malloc(sizeof(char*)*number_of_row);
for(i=0;i<number_of_row; i++)
list[i] = malloc(sizeof(char)*number_of_col);
Additionally, if you are allocating memory dynamically. you are to free it as work done:
for(i=0;i<number_of_row; i++)
free(list[i] );
free(list);
EDIT
In you revised question:
int wordLine = 0, counter = 0, i;
wordLine
and counter
are 0
before this code:
list = malloc(sizeof(char*)*wordLine+1);
for(i = 0;i < wordLine ; i++)
list[i] = malloc(sizeof(char)*counter);
you have to assign value to wordLine
and counter
variable
Also memory allocation should be before the following loop(outside):
while((c = fgetc(myFile)) != EOF){
:
:
}
EDIT:
New your third version of question. You are reading file two times. So you need to fseek(), rewind() to first char before second loop starts.
try with:
fseek(fp, 0, SEEK_SET); // same as rewind()
rewind(fp); // same as fseek(fp, 0, SEEK_SET)
also I have doubt in your logic to calculate numberOfLines
and maxNumberOfChars
. please check that also
EDIT
I think your calculation for maxNumberOfChars = 0, numberOfLines = 0
is wrong try like this:
maxNumberOfChars = 0, numberOfLines = 0, numberOfChars = 0;
while((c = fgetc(myFile)) !=EOF){
if(c == '\n'){
numberOfLines++;
if(maxNumberOfChars < numberOfChars)
maxNumberOfChars = numberOfChars;
numberOfChars=0
}
numberOfChars++;
}
maxNumberOfChars
is max number of chars in a line.
Also change code:
malloc(sizeof(char)*(maxNumberOfChars + 1));
Solution 2
If I were you, I'd map the file to private memory, using mmap
, and then iterate over the file, storing starts of words in an array of char**
that you can increase as you go with realloc
, and replacing line breaks with 0.
That way, you have your words in memory as a continuous block, you don't have to care about file I/O, because you have the entire text file in memory as char*
, and you don't have to malloc an array of arrays.
For information on the functions, see the respective man pages, or drop me a comment :)
EDIT: If you don't know mmap yet, have a look at this: http://www.jimscode.ca/index.php/component/content/article/13-c/45-c-simple-mmap-example
Most C programmers today still try to read files into memory using fopen
and friends, but that's completely unnecessary and introduces additionel levels of complexity. (buffering, growing arrays, ...) and mmap
is a nice alternative that moves all the nasty work down to the OS
ShadyBears
Updated on June 13, 2022Comments
-
ShadyBears about 2 years
How would I go about dynamically allocating memory to char** list in this function?
Basically the idea of this program is I have to read in a list of words from a file. I cannot assume max strings or max string length.
I have to do other stuff with the C-strings but that stuff I should be fine with.
Thanks!
void readFileAndReplace(int argc, char** argv) { FILE *myFile; char** list; char c; int wordLine = 0, counter = 0, i; int maxNumberOfChars = 0, numberOfLines = 0, numberOfChars = 0; myFile = fopen(argv[1], "r"); if(!myFile) { printf("No such file or directory\n"); exit(EXIT_FAILURE); } while((c = fgetc(myFile)) !=EOF) { numberOfChars++; if(c == '\n') { if(maxNumberOfChars < numberOfChars) maxNumberOfChars += numberOfChars + 1; numberOfLines++; } } list = malloc(sizeof(char*)*numberOfLines); for(i = 0; i < wordLine ; i++) list[i] = malloc(sizeof(char)*maxNumberOfChars); while((c = fgetc(myFile)) != EOF) { if(c == '\n' && counter > 0) { list[wordLine][counter] = '\0'; wordLine++; counter = 0; } else if(c != '\n') { list[wordLine][counter] = c; counter++; } } }