chakeda chakeda - 1 month ago 15
C Question

Reuse Array of Char Pointers

Suppose I want to "reuse" an array of char pointers, like in the following program that loops files given in the argument list, loops the lines in the file, adds them to a dynamically allocated array, then prints it:

// includes
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

// globals
int progReturn = 0;
int globalLineCounter = 0;



////// main
int main(int argc, char *argv[]) {
FILE *fp;
int i;


// iterate files. first arg is the program name
for (i = 1; i < argc; i++) {
fp = fopen(argv[i], "r");
if (fp == NULL) {
fprintf(stderr, "The file '%s' did not exist.\n", argv[i]);
progReturn = 1;

} else {

// read lines from the file
char line[256];

// THE PROBLEM: I'd like to completely clear this array.
char **lines = malloc(16 * sizeof(char*));

// iterate lines
int fileLineCounter = 0;
while (fgets(line, sizeof(line), fp)) {

// remove newline
strtok(line, "\n");

// add lines to array
lines[globalLineCounter] = malloc(256 * sizeof(char));
strcpy(lines[globalLineCounter], line);
//printf("%s\n", lines[globalLineCounter]); // tester

fileLineCounter++;
globalLineCounter++;
}
// all lines read
printf("The file '%s' had %d lines.\n", argv[i], fileLineCounter);

// print the array
int j=0;
for (j=0; j<fileLineCounter; j++) {
// PROBLEM: Garbage from the second file when it prints here.
printf("%s\n", lines[j]);
}

// delete lines, delete file
memset(lines, 0, sizeof(*lines));
fclose(fp);
}
}
// all files read

return progReturn;
}


On the first file, everything works with no problems. On the second file, when I print the array, It shows unprintable characters, and some of the lines from the first file.

What could be causing this issue? Am I not fully clearing
**lines
?




EDIT: example input and output:

input file foo:

This is a test
of the lineSort program
in order to
test its capabilities.
Lots of whitespace too!
aaa

bbb

cccccc



aaa
ggggg
hhhhh
fffff
eeeee
ddddd
ppppp


input file bar:

aaaaaaaaaaaaaaaaa
bbbbbbbbbbbbbbbbb
zzzzzzzzzzzzzzzzz
ccccccccccccccccc
yyyyyyyyyyyyyyyyy


output for
sortLine foo bar
:

The file 'foo' had 20 lines.





cccccc
Lots of whitespace too!
This is a test
aaa
aaa
bbb
ddddd
eeeee
fffff
ggggg
hhhhh
in order to
of the lineSort program
ppppp
test its capabilities.
The file 'bar' had 5 lines.
(x▒▒
(x▒▒
Lots of whitespace too!
in order to
test its capabilities.

Answer
    strcpy(lines[globalLineCounter], line);

This looks like your main problem. globalLineCounter keeps increasing across all input files.

Let's say your first input file contains 10 lines and your second file 5 lines. Then your code will create a dynamic array (of dynamic arrays) and store the lines from the first file in elements 0 .. 9 (and then print them). You never free any of the allocated memory, so it all leaks at the end of the loop.

For the second file, you create another dynamic array. You store the 5 lines from the second file in elements 10 .. 14 (via globalLineCounter), but then print elements 0 .. 4 (fileLineCounter). Those elements are uninitialized and contain garbage.