Thread: malloc and array of pointers

  1. #1
    Registered User
    Join Date
    Jul 2012
    Location
    Australia
    Posts
    242

    malloc and array of pointers

    Hi all.

    I am trying to compile the below program and getting these errors:

    Code:
    |In function ‘main’:|
    18|error: incompatible types when assigning to type ‘char *[30]’ from type ‘char *’|
    19|warning: passing argument 1 of ‘strcpy’ from incompatible pointer type [enabled by default]|
    /usr/include/string.h|128|note: expected ‘char * __restrict__’ but argument is of type ‘char **’|
    20|error: lvalue required as increment operand|
    ||=== Build finished: 3 errors, 1 warnings ===|
    Why are the types incompatible with malloc? filename == filename[0]? So what is the problem? My reference books has not provided any solutions. Thanks.

    Code:
    #include <stdio.h>
    #include <dirent.h>
    #include <stdlib.h>
    #include <string.h>
    
    int main(void)
    {
        DIR *dirname;
        struct dirent *direntries;
        char *filename[30];
    
        dirname = opendir("/home/test/Downloads");
    
        if(dirname != NULL)
        {
            while((direntries = readdir(dirname)))
            {
                filename = (char *) malloc(strlen(direntries->d_name));
                strcpy(filename, direntries->d_name);
                filename++;
            }
            (void) closedir(dirname);
        }
        else
        {
            perror("Error opening directory");
        }
    
        return 0;
    }
    Last edited by cfanatic; 09-12-2012 at 11:56 PM.
    IDE: Code::Blocks | Compiler Suite for Windows: TDM-GCC (MingW, gdb)

  2. #2
    Registered User
    Join Date
    Apr 2008
    Posts
    396
    "filename" is an array of strings (char*[30]), you try to assign it a string (char*). You have to either dereference (*filename = (char*)malloc...) it or specify an index (filename[i]=...).

    But what you're doing is wrong, "filename", being an array, is a readonly value, you can't reassign it, that's why you get that error line 20 with filename++, your compiler tells you it's not a lvalue. You'll have to either access that array using indices, or declare an additional pointer (char**) to walk it using an increment operator.
    Indeed, in assembly, an array is just the address of its first element, but as you see here, they are not equivalent.
    Last edited by root4; 09-13-2012 at 12:14 AM.

  3. #3
    Registered User
    Join Date
    Jul 2012
    Location
    Australia
    Posts
    242
    I had tried *filename = ...., and file[0] = .....

    But that gives me different warnings:

    Code:
    |In function ‘main’:|
    19|warning: passing argument 1 of ‘strcpy’ from incompatible pointer type [enabled by default]|
    /usr/include/string.h|128|note: expected ‘char * __restrict__’ but argument is of type ‘char **’|
    20|error: lvalue required as increment operand|
    ||=== Build finished: 2 errors, 1 warnings ===|
    I tried &filename[0] = ... , and that gives even more errors.
    IDE: Code::Blocks | Compiler Suite for Windows: TDM-GCC (MingW, gdb)

  4. #4
    TEIAM - problem solved
    Join Date
    Apr 2012
    Location
    Melbourne Australia
    Posts
    1,907
    You should be putting the returned address into the first element in the array - filename[0].

  5. #5
    TEIAM - problem solved
    Join Date
    Apr 2012
    Location
    Melbourne Australia
    Posts
    1,907
    filename == filename[0]?
    This assumption is wrong.

    filename == &filename[0]

  6. #6
    Registered User
    Join Date
    Apr 2008
    Posts
    396
    You still have errors because "filename" is an array, not a pointer, I've edited my previous post, please re-read it.

  7. #7
    Registered User
    Join Date
    Jul 2012
    Location
    Australia
    Posts
    242
    I still can't get it work. I am going to reread the section on pointers again. Thanks for the replies.
    IDE: Code::Blocks | Compiler Suite for Windows: TDM-GCC (MingW, gdb)

  8. #8
    Registered User
    Join Date
    Apr 2008
    Posts
    396
    What have you changed?

  9. #9
    Registered User
    Join Date
    Jul 2012
    Location
    Australia
    Posts
    242
    Code:
    #include <stdio.h>
    #include <dirent.h>
    #include <stdlib.h>
    #include <string.h>
    
    int main(void)
    {
        DIR *dirname;
        struct dirent *direntries;
        char *filename[30];
        int x = 0;
    
        dirname = opendir("/home/phuong/Downloads");
    
        if(dirname != NULL)
        {
            while((direntries = readdir(dirname)))
            {
                filename[x] = (char *) malloc(strlen(direntries->d_name));
                strcpy(filename[x], direntries->d_name);
                x++;
            }
            (void) closedir(dirname);
        }
        else
        {
            perror("Error opening directory");
        }
    
        return 0;
    }
    IDE: Code::Blocks | Compiler Suite for Windows: TDM-GCC (MingW, gdb)

  10. #10
    TEIAM - problem solved
    Join Date
    Apr 2012
    Location
    Melbourne Australia
    Posts
    1,907
    Code:
    filename[x] = (char *) malloc(strlen(direntries->d_name)+1);

  11. #11
    Registered User
    Join Date
    Apr 2008
    Posts
    396
    It's ok, just be sure to reset the array content:
    Code:
    char* filename[30] = {};
    also fix what click_here said above.
    If you run your code and print the content of the array, with e.g.
    Code:
    for(size_t i = 0; i < sizeof(filename)/sizeof(*filename) && filename[i]; ++i) fprintf(stderr, "* %s\n", filename[i]);
    you'll see the list of your files.
    Do you expect something else?

  12. #12
    Registered User
    Join Date
    Jul 2012
    Location
    Australia
    Posts
    242
    Quote Originally Posted by root4 View Post
    Code:
    for(size_t i = 0; i < sizeof(filename)/sizeof(*filename) && filename[i]; ++i) fprintf(stderr, "* %s\n", filename[i]);
    I just used a boring for loop.
    Code:
    #include <stdio.h>
    #include <dirent.h>
    #include <stdlib.h>
    #include <string.h>
    
    int main(void)
    {
        DIR *dirname;
        struct dirent *direntries;
        char *filename[30];
        int i, x = 0;
    
        dirname = opendir("/home/aspire/Documents");
    
        if(dirname != NULL)
        {
            while((direntries = readdir(dirname)))
            {
                filename[x] = (char *) malloc(strlen(direntries->d_name) + 1);
                strcpy(filename[x], direntries->d_name);
                x++;
            }
            (void) closedir(dirname);
        }
        else
        {
            perror("Error opening directory");
        }
    
        for(i = 0; i < x; i++)
        {
            printf("%s\n", filename[i]);
            free(filename[i]);
        }
    
        return 0;
    }
    IDE: Code::Blocks | Compiler Suite for Windows: TDM-GCC (MingW, gdb)

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 7
    Last Post: 05-19-2010, 02:12 AM
  2. Malloc and pointers
    By taurus in forum C Programming
    Replies: 8
    Last Post: 10-25-2008, 09:00 AM
  3. Problem with malloc and pointers to pointers
    By mike_g in forum C Programming
    Replies: 7
    Last Post: 03-29-2008, 06:03 PM
  4. malloc and pointers
    By St0rM-MaN in forum C Programming
    Replies: 14
    Last Post: 06-20-2007, 11:03 AM
  5. Pointers and malloc
    By Unregistered in forum C Programming
    Replies: 2
    Last Post: 03-21-2002, 09:20 PM