Thread: Problem with malloc and pointers to pointers

  1. #1
    Dr Dipshi++ mike_g's Avatar
    Join Date
    Oct 2006
    Location
    On me hyperplane
    Posts
    1,218

    Problem with malloc and pointers to pointers

    In this function I am trying to malloc an array of pointers, then for each pointer malloc space for a string. It compiles, but segfaults at the highlighted line. What am I doing wrong?
    Code:
    int LoadWordList(char *fname, char **list)
    {
    	FILE *fp = fopen(fname, "r");
    	char ch;
    	char string[MAX_LEN];
    	int linecount = 0, i, len;
    
    	if(! fp)			
    	{
    		printf("Error: Unable to open wordlist file.\n");
    		exit(EXIT_FAILURE);
    	}
    	while((ch = fgetc(fp)) != EOF)
    		if(ch == '\n') linecount++;
    	rewind(fp);
    
    	*list = (char*)malloc(linecount+1);
    
    	for(i=0; i<linecount; i++)
    	{
    		fgets(string, MAX_LEN, fp);
    		len = strlen(string);
    		list[i] = (char*)malloc(len+1);  // Segfaults here
    		//strcpy(list[i], string);
    		//printf("%s", list[i]);
    	}		
    	return linecount;
    }
    Cheers.

  2. #2
    Dr Dipshi++ mike_g's Avatar
    Join Date
    Oct 2006
    Location
    On me hyperplane
    Posts
    1,218
    Ok I think I figured it out. This seems to work:
    Code:
    int LoadWordList(char *fname, char **list)
    {
    	FILE *fp = fopen(fname, "r");
    	char ch;
    	char string[MAX_LEN];
    	int linecount = 0, i, len;
    
    	if(! fp)			
    	{
    		printf("Error: Unable to open wordlist file.\n");
    		exit(EXIT_FAILURE);
    	}
    	while((ch = fgetc(fp)) != EOF)
    		if(ch == '\n') linecount++;
    	rewind(fp);
    
    	list = (char**)malloc(linecount+1);
    
    	for(i=0; i<linecount; i++)
    	{
    		fgets(string, MAX_LEN, fp);
    		len = strlen(string);
    		list[i] = (char*)malloc(len+1);  
    		strcpy(list[i], string);
    		printf("%s", list[i]);
    	}		
    	return linecount;
    }
    Sorry for wasting your time

  3. #3
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    What about doing
    Code:
    *list = (char *)malloc(linecount*sizeof(char *))
    so that *list is in fact an array of char *, instead of char?

  4. #4
    Chinese pâté foxman's Avatar
    Join Date
    Jul 2007
    Location
    Canada
    Posts
    404
    Well, you might need to add another level of indirection to your second parameter... something like

    Code:
    int LoadWordList(char *fname, char ***list)
    {
       // ...
       *list = malloc(linecount * sizeof(char *));
       
       // ...
       for (i = 0; i < linecount; i++)
       {
          // ...
          (*list)[i] = malloc((len + 1) * sizeof(char));
       }
    
       // ...
    }
    
    int main()
    {
       char **list;
       LoadWordList("someArgument", &list);
       // ...
    }
    By the way, if you use the "figure it out" code you just posted, your second parameter become useless since you are not using the value of it, just putting a result of malloc in it. In fact, i believe what you just posted doesn't work.
    I hate real numbers.

  5. #5
    Dr Dipshi++ mike_g's Avatar
    Join Date
    Oct 2006
    Location
    On me hyperplane
    Posts
    1,218
    Erm, yeah good point. My way worked but crashed when I try and access stuff bak in main. Problem is I can't seem to get your way to work either. It Segfaults on the same line where I malloc space for the strings:
    Code:
    		list[i] = (char*)malloc(len+1);

  6. #6
    Dr Dipshi++ mike_g's Avatar
    Join Date
    Oct 2006
    Location
    On me hyperplane
    Posts
    1,218
    Ok, I tried the way you suggested foxman, but gcc gave errors about incompatible pointer types . I got it to compile by adding another * to the first malloc, but then it segfaulted. If possible I'd really like to avoid the extra indirection as it makes things confusing.

    Edit: this is what I had:
    Code:
    int LoadWordList(char *fname, char ***list)
    {
    	FILE *fp = fopen(fname, "r");
    	char ch;
    	char string[MAX_LEN];
    	int linecount = 0, i, len;
    
    	if(! fp)			
    	{
    		printf("Error: Unable to open wordlist file.\n");
    		exit(EXIT_FAILURE);
    	}
    	while((ch = fgetc(fp)) != EOF)
    		if(ch == '\n') linecount++;
    	rewind(fp);
    
    	**list = (char*)malloc((linecount)*sizeof(char*));
    
    	for(i=0; i<linecount; i++)
    	{
    		fgets(string, MAX_LEN, fp);
    		len = strlen(string);
    		(*list)[i] = (char*) malloc(len+1);  // Segfaults here
    		//strcpy(list[i], string);
    	}		
    	return linecount;
    }

  7. #7
    Chinese pâté foxman's Avatar
    Join Date
    Jul 2007
    Location
    Canada
    Posts
    404
    Indeed, i'm not quite sure to understand why it's not working for you because i just tested it and it does work, and got no warnings concerning incompatible pointer types. I use Visual Studio 2005, with the compiling as C code option and warning set to max.

    Here is the source code
    Code:
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    #define NOM_FICH "test.txt"
    #define MAX_LEN 200
    
    int LoadWordList(char *fname, char ***list)
    {
    	FILE *fp = fopen(fname, "r");
    	char ch;
    	char string[MAX_LEN];
    	int linecount = 0, i, len;
    
    	if(! fp)			
    	{
    		printf("Error: Unable to open wordlist file.\n");
    		exit(EXIT_FAILURE);
    	}
    	while((ch = fgetc(fp)) != EOF)
    		if(ch == '\n') linecount++;
    	rewind(fp);
    
    	*list = malloc(linecount * sizeof(char *));
    
    	for(i=0; i<linecount; i++)
    	{
    		fgets(string, MAX_LEN, fp);
    		len = strlen(string);
    		(*list)[i] = malloc((len + 1) * sizeof(char));
    		strcpy((*list)[i], string);
    	}		
    	return linecount;
    }
    
    int main()
    {
       char **list;
       int i;
       int nbElement;
    
       nbElement = LoadWordList(NOM_FICH, &list);
       for (i = 0; i < nbElement; i++)
       {
           printf("&#37;s", list[i]);
       }
    
       return 0;
    }
    And here the "test.txt" file i was using
    Code:
    this
    is
    a
    random
    test
    I hate real numbers.

  8. #8
    Dr Dipshi++ mike_g's Avatar
    Join Date
    Oct 2006
    Location
    On me hyperplane
    Posts
    1,218
    Ok I see what my problem was. It was that I was still castiing the return value of malloc. Thanks foxman, that works. I guess the extra indirection is needed if i want to save the content of the list without returning the list pointer.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Structures, arrays, pointers, malloc.
    By omnificient in forum C Programming
    Replies: 9
    Last Post: 02-29-2008, 12:05 PM
  2. Problems with pointers and malloc()
    By Deirdre in forum C Programming
    Replies: 3
    Last Post: 10-28-2007, 04:20 PM
  3. Malloc and calloc problem!!
    By xxhimanshu in forum C Programming
    Replies: 19
    Last Post: 08-10-2005, 05:37 AM
  4. pointers
    By InvariantLoop in forum C Programming
    Replies: 13
    Last Post: 02-04-2005, 09:32 AM
  5. malloc problem in SUN in 64-bit compilation
    By ylzhang in forum C Programming
    Replies: 6
    Last Post: 05-31-2003, 11:48 AM