2

All I'm doing is initiating a double pointer in c (char*) to hold my array of strings. I pass this variable (char* array_strings) into another function which should open a file and create an array of strings representing each line of the file, but for some reason when I return from the function the variable array_strings is null.

int main(void) {
    char **array_strings;
    char *book_file = "book.txt";
    delimitByNewline(book_file, array_strings);
    return 1;
}

//delimit file

void delimitByNewline(char *book, char **array) {
    int count = 0;
    int i = 0;
    char c;
    int size = fileLines(book);
    srand(time(NULL));
    char **ret_array = (char **)malloc(sizeof(char *) * size);

    FILE *bk = fopen(book, "rt");
    if(!bk) {
        perror("fp");
        exit(1);
    }

    char *line = (char *)malloc(sizeof(char)*60);

    while ((c = fgetc(bk)) != EOF) {
        line[i] = c;
        i++;
        if(c == '\n') {
            ret_array[count] = line;
            line = (char *)malloc(sizeof(char) * i);
            count++;
            i = 0;
        }

    }

    fclose(bk);
    array = ret_array;
    free(line);
    free(ret_array);
}
ajay
  • 9,402
  • 8
  • 44
  • 71
Dante Hoyte
  • 333
  • 2
  • 15
  • 2
    "Initiating" is what you do to freshmen in the school toilet. "Initializing" is what you do with variables in C. – Kerrek SB Feb 18 '14 at 19:14
  • Note that `free(ret_array)` at the end of your function deletes the data you try to return. – VoidStar Feb 18 '14 at 19:16
  • The initialing comment was very helpful....thank you. Anyways, yes, even before I added the free, the value of the array remained null. But I'll recompiling it to make sure – Dante Hoyte Feb 18 '14 at 20:11

2 Answers2

4

Since you are allocating the collection in the function, you need to return it to the caller.

I would suggest changing the return signature from void to char ** and changing the flow to this:

char** delimitByNewline(char* book){
   char** ret_array = (char **)malloc(sizeof(char *)*size);
   // .. assign the strings, don't free!
   return ret_array;
}

and called like so:

char* book_file = "book.txt";
char** array_strings = delimitByNewline(book_file);

(And please heed @JonathanLeffler's comment - ownership of the heap-allocated ret_array passes back to the caller - i.e. caller must free, not delimitByNewLine(). !)

Edit

If you really want to pass the array as an out parameter, you'll need to pass the address of the original pointer, since the function will need it to assign the address of the malloced array i.e.:

char **array_strings = 0; // NULL
char *book_file = "book.txt";
delimitByNewline(book_file, &array_strings);
// do stuff
// free strings + array

Which then needs to be dereferenced to assign it.

void delimitByNewline(char *book, char ***array) {
    *array = (char **)malloc(sizeof(char *) * size);
    // ... Don't free
StuartLC
  • 104,537
  • 17
  • 209
  • 285
1

In function void delimitByNewline(char* book,char** array) arguments types are incorrect. You are passing addresses and writing to type of char * & char **.

FILE *bk = fopen(book,"rt"); What is t in file access mode ?

Sunil Bojanapally
  • 12,528
  • 4
  • 33
  • 46
  • `"rt"` is a Windows-ism equivalent to `"r"` for reading a text file (and in contrast to `"rb"` for reading a binary file). The binary vs text distinction is immaterial on Unix. The C standard support 'implicit' text mode by not specifying `"b"`. – Jonathan Leffler Feb 18 '14 at 19:18