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);
}
3
  • 2
    "Initiating" is what you do to freshmen in the school toilet. "Initializing" is what you do with variables in C. Commented Feb 18, 2014 at 19:14
  • Note that free(ret_array) at the end of your function deletes the data you try to return. Commented Feb 18, 2014 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 Commented Feb 18, 2014 at 20:11

2 Answers 2

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
Sign up to request clarification or add additional context in comments.

4 Comments

And make sure you don't free(ret_array) before returning!
Ok, I'll try that. But is there a way to do it by just assuaging the address of the variable to a new value?
Wow, I meant changing the address of the variable to a new one
@user2099522 updated. The return and assign approach looks easier on the eye IMO.
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 ?

1 Comment

"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".

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.