0

I am trying to create a 2d array dynamically, then open a txt file and copy each lenient my 2d array. Then save this array back to my main. I keep running into a segmentation error. Any suggestions how to do fix this code? BTW i think the problem stars after the 2nd time while loop occurs...

    #include<stdio.h>

    char **randomArrayofStrings(){
        char **twoArray=null;
        int rows=50;
        int col=20;
        i=0;
        FILE *file=null;
        int messageSize=50;//this is number is trivial
        file = fopen("somefile.txt","r");
        twoArray= malloc(rows*sizeof(char*));
        for(i=0;i<col;i++)
        {
             twoArray[i]=malloc(rows*sizeof(char));
             strcpy(twoArray[i], "some random word");
        }
        while(!feof(file))
        {
             fgets(dArray[i],messageSize, file);
             strtok(dArray[i], "\n");
             i++;
        }   
        return twoArray;
    }


    int main(int argc, char **argv)
    {
        char **localArray=null;
        localArray=randomArrayofStrings();
        for(i=0;i<20;i++)//20 is just a random number
             printf("Strings: %s", localArray[i]);
    }
Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
bluestar99
  • 11
  • 6

2 Answers2

2

As I see, in your function randomArrayofStrings loop for goes through columns "i cols in your code. So, you allocate array of pointers first and consider it as cols and then in a loop you allocate rows.

And after malloc check the value that was returned and do not use the pointer if it is NULL after memory allocation.

To free allocated memory, use the inverted sequence - free all rows in a loop and than free cols once. E.g.:

        for(i=0;i<col;i++){
            free(twoArray[i]);
        }
        free(twoArray);
        twoArray = NULL;

EDIT:

And also, to use malloc and free you need #include <stdlib.h>, and #include <string.h> for strcopy, int i=0; should be instead of i=0;, and correct null value for pointers is NULL.

And what is dArray? I do not see the declaration or definition? Dou you mean twoArray?

EDIT2:

The following is my version of your program:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char **randomArrayofStrings(){
    char **twoArray=NULL;
    char * ptr = NULL;
    int rows=50; // this will be also message size
    int cols=20;
    int i=0;
    FILE *file=NULL;
    file = fopen("somefile.txt","r");
    if( file == NULL )
        return NULL;
    twoArray = (char**) malloc(cols * sizeof(char*));
    if(twoArray == NULL)
    {
        return NULL;
    }
    for(i=0;i<cols;i++)
    {
        twoArray[i] = (char*)malloc(rows*sizeof(char));
        if(twoArray[i] == NULL)
            return NULL;
        strcpy(twoArray[i], "some random word");
    }
    i = 0; // reset counter
    while(!feof(file))
    {
        fgets(twoArray[i], rows, file);
        ptr = strchr(twoArray[i],'\n');
        if( ptr )
            *ptr = '\0';
        else
            twoArray[i][rows-1] = '\0';
        i++;
        if( i >= cols)
            break;
    }   
    fclose(file);
    return twoArray;
}

void freeMy2dArray(char **twoArray, int n)
{
    int i;
    for(i=0; i < n; i++){
         free(twoArray[i]);
    }
    free(twoArray);
    twoArray = NULL;
}


int main(int argc, char **argv)
{
    int i;
    char **localArray=NULL;
    localArray = randomArrayofStrings();
    if( localArray == NULL )
        return 1;
    for(i=0;i<20;i++)//20 is just a random number
        printf("Strings: %s\n", localArray[i]);
    freeMy2dArray(localArray, 20);
}
VolAnd
  • 6,367
  • 3
  • 25
  • 43
1

You are not suppossed to free() twoArray inside randomArrayofStrings(). You have to free them inside main(), once you're done with using the allocated memeory.

That said, the way you're using sizeof(localArray) in main() is wrong. You have to use the exact value you did use to poupulate twoArray.

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
  • i dont understand how I can free(twoArray) if once I copy its address to localArray, ( from my noob knowledge) main has no way of accessing and free twoArray – bluestar99 Mar 31 '15 at 05:09
  • @RT89 OK then, if the above is true, why're you returning the `twoArray`? It should not be usable in `main()`, right? Well, it __is__ usable and valid inside `main()` untill and unless you `free()` it. Dynamic memory allocation scope is global and as long as you have a _valid_ pointer to access that, it is fine. – Sourav Ghosh Mar 31 '15 at 05:11
  • @RT89 You're aloocating memory and returning the pointer `twoArray` which is collected in `localArray`. so, you can use `localArray` to access the memory, same way as you would have used `twoArray`. – Sourav Ghosh Mar 31 '15 at 05:13
  • if i understand you correctly then I could add free(twoArray) after this line: (localArray=randomArrayofStrings();) – bluestar99 Mar 31 '15 at 05:14
  • @RT89 not likely. see my above comment. – Sourav Ghosh Mar 31 '15 at 05:14
  • @RT89 First you have to free each element in `localArray`, then `localArray` itself. – Sourav Ghosh Mar 31 '15 at 05:16