Thread: Passing arrays of pointers into functions

  1. #1
    Registered User
    Join Date
    Jan 2007
    Posts
    14

    Question Passing arrays of pointers into functions

    Hello again everyone,
    Still working on my program to store a list of mp3 details from a text file.
    I've been writing a few functions to perform different operations on the stored information, such as; sort all the songs alphabetically by artist (using a bucket sort) and create playlists (using linked lists).
    The mp3 info is stored in a structure like this:
    Code:
    typedef struct mp3info
    {
       char title[100];
       char artist[100];
       char album[100];
       char genre[100];
    } SONG;
    The memory location of each SONG structure is then stored in an array of pointers, so that if I wanted to print the artist of track 1054 I could do this:
    Code:
    printf ( "Artist: %s", array[1054]->artist );
    Now, if I wanted to do this within a function, I assumed I would do this:
    Code:
    void printsong ( int tracknumber, SONG *array[2000] )
    {
       printf ( "Track: %d\n", tracknumber );
       printf ( "Title: %s\n", array[tracknumber]->title );
       printf ( "Artist: %s\n", array[tracknumber]->artist );
       printf ( "Album: %s\n", array[tracknumber]->album );
       printf ( "Genre: %s\n", array[tracknumber]->genre );
    }
    
    int main ( void )
    {
       SONG *array[2000]; //assume track details are already stored in array
       int tracknumber;
    
       /* Print track 3 */
    
       tracknumber = 3;
    
       printsong ( tracknumber, array );
    
       return 0;
    }
    This is just a simple example of the type of thing I'm having trouble with. Am I doing anything wrong when passing the array? If I try to print details from the array within the main function everything seems to work fine.
    Thanks for everyone who's helped me with this so far! Wouldn't have managed without all your help and advice!

  2. #2
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    You have an array of pointers. All you really need is an array. What's your reasoning behind thinking you need an array of pointers?


    Quzah.
    Hope is the first step on the road to disappointment.

  3. #3
    Registered User
    Join Date
    Jan 2007
    Posts
    14
    Just because I wasn't sure about getting data from an array of structures.
    If I did have an array of structures like this:
    Code:
    SONG array[2000];
    would I print the title of track 5, for example, like this?
    Code:
    printf ( "Title: %s", array[5].title );
    Is it easy for me to pass full arrays into functions?
    I just chose pointers because i thought I had a good understanding of how to use them.

  4. #4
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    You can always make a small example and find out. Then post when you're stuck. The problem with your pointer example is that you just have a bunch of pointers, and you don't have anything allocated for each one of them. Also, it's just an extra step of indirection you don't need to bother with.


    Quzah.
    Hope is the first step on the road to disappointment.

  5. #5
    Registered User
    Join Date
    Jan 2007
    Posts
    14
    Right, I've had a bit of a mess around with the program. Now the information is stored in an array of structures (The trim function just gets rid of the spaces at the beginning and end of strings so that can be ignored). The store function takes the different information (tracknumber, title, artist etc.) and stores it into the write place using a pointer to the array in the main function.
    Again, the problems occuring when the program reaches the store function.
    I'm getting these warnings but don't really follow what they mean (I'm still fairly new to this). I'm passing the array into the function as I would any other variable but it just doesnt seem to work.

    Code:
    warning C4047: 'function' : 'struct mp3info ** ' differs in levels of indirection from 'struct mp3info (*)[100]'
    'store' : different types for formal and actual parameter 2
    Herer's the code. Please let me know if you can see where I'm going wrong

    Code:
    /* A program to take information from a .txt file and store it in structures */
    
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <console_lib.h>
    #include <conio.h>
    
    typedef struct mp3info
    {
    	char title[100];
    	char artist[100];
    	char album[100];
    	char genre[100];
    } SONG;
    
    /* ------------------------------------------------------------------------ */
    
    char *trim ( char *string )
    {
    	int length = strlen ( string );
    	int start = 0;
    	int end = length - 1;
    	char *trimmed;
    	int n = 0;
    
    	/* Check to make sure a string has been input into function */
    
    	if ( string == 0 )
    		printf ( "Error: string to be trimmed has a null value\n" );
    
    	/* Find the first letter in the string that is not a space bar */
    
    	while ( string[start] == ' ' )
    		start++;
    
    	/* Find the last letter in the string that is not a space bar */
    
    	while ( string[end] == ' ' )
    		end--;
    
    	/* Allocate memory for trimmed string */
    
    	trimmed = ( char *) malloc ( 2 + end - start );
    
    	/* Copy new string */
    
    	strncpy (trimmed, string + start, end - start + 1);
    
    	/* Add null terminator */
    
    	trimmed[end] = 0;
    
    	return trimmed;
    }
    
    /* ------------------------------------------------------------------------ */
    
    void store ( char string[500], SONG *array[100] )
    {	
    	char delim[] = "-";
    	char *token = NULL;
    	int tracknumber;
    
    	/* Extract track number */
    	
    	token = strtok ( string, delim );
    	tracknumber = atoi ( token );
    
    	/* Extract and store title */
    
    	token = strtok ( NULL, delim );
    	token = trim ( token );
    	strcpy ( array[tracknumber]->title, token );
    	free ( token );
    
    	/* Extract and store artist */
    
    	token = strtok ( NULL, delim );
    	token = trim ( token );
    	strcpy ( array[tracknumber]->artist, token );
    	free ( token );
    
    	/* Extract and store album */
    
    	token = strtok ( NULL, delim );
    	token = trim ( token );
    	strcpy ( array[tracknumber]->album, token );		
    	free ( token );
    
    	/* Extract and store genre */
    
    	token = strtok ( NULL, delim );
    	token = trim ( token );
    	strcpy ( array[tracknumber]->genre, token );
    	free ( token );;
    }
    
    /* ------------------------------------------------------------------------ */
    
    int main (void)
    {
    	char string[500];
    	int tracknumber = 0;
    	SONG array[100];
    
    	/* Open file mp3list.txt for reading */
    
    	FILE *fp;
    	fp = fopen ( "C:\\mp3list.txt", "r" );
    
    	/* Store the info for the first 100 mp3s */
    
    	do
    	{
    		fgets ( string, 500, fp );
    		store ( string, &array );
    	}
    	while ( tracknumber < 100 );
    
    	printf ( "Loading Complete!\n\n");
    
    	return 0;
    
    }

  6. #6
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    It's clear that you have no idea how pointers and arrays work, so here's an example of what you need to do if you want to use your current method.

    Step 1: Creating the array of pointers.
    Code:
    int *pa[ SOMESIZE ];
    Make an array of pointers. These pointers don't actually point to any usable data. You can't use them now, other than to make them point at something. This means...

    Step 2: Making the pointers point somewhere meaningful.
    Code:
    size_t x;
    for( x = 0; x < SOMESIZE; x++ )
    {
        pa[ x ] = malloc( sizeof( int ) );
    }
    You need to allocate a block of memory for each pointer. Naturally you'll want to test the value before you use it, to make sure malloc didn't fail. I'll leave that to you. Your array of pointers, which now actually point to usable memory, still don't contain any worthwhile values. And so...

    Step 3: Filling the pointed to memory with something valid.
    Code:
    for( x = 0; x < SOMESIZE; x++ )
    {
        *pa[ x ] = somedata( );
    }
    You have to dereference the pointer to put something in what it points at. You have to index the array to get to the spot holding the appropriate pointer. Now that you're done filling, you can do something with it.

    Step 4: Whatever.
    Code:
    for( x = 0; x < SOMESIZE; x++ )
    {
        printf( "pa[ %d ]'s pointer points to an object storing %d\n", x, *pa[ x ] );
    }
    Like above, you do the same thing to get the value of whatever you've set. Now that we're done with it...

    Step 5: Free what you allocate.
    Code:
    for( x = 0; x < SOMESIZE; x++ )
    {
        free( pa[ x ] ); 
        pa[ x ] = NULL; 
    }
    free doesn't set the freed pointer to NULL, so if you plan on using it over again in the future, you'll want to do it manually after you free it.

    Now what I'm sure you'd rather be doing...

    Step 1: Make an array.
    Code:
    int array[ SOMESIZE ];
    No pointers needed. Let's fill it.

    Step 2: Fill it with something useful.
    Code:
    size_t x;
    for( x = 0; x < SOMESIZE; x++ )
    {
        array[ x ] = getavalue( );
    }
    No extra indirection needed. So now we're done with it.

    Step 3: There is no Step 3.


    Arrays are passed to functions as pointers to their first element. That means you can simply pass the array name to a function which takes an array of the same type, and use it. Any changes you make to it will keep after the function returns.
    Code:
    void foo( int a[], size_t x );
    ...
    foo( array, SOMESIZE );
    ...
    
    void foo( int a[], size_t y )
    {
        while( y )
        {
            a[ y-- - 1 ] ++;
        }
    }
    And there you have it.


    Quzah.
    Hope is the first step on the road to disappointment.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 12
    Last Post: 06-06-2008, 05:26 PM
  2. newbie problems with pointers arrays and functions.
    By MegaManZZ in forum C++ Programming
    Replies: 6
    Last Post: 01-08-2008, 05:33 PM
  3. Passing pointers to arrays of char arrays
    By bobthebullet990 in forum C Programming
    Replies: 5
    Last Post: 03-31-2006, 05:31 AM
  4. Help Understanding Passing Arrays To Functions
    By jrahhali in forum C++ Programming
    Replies: 7
    Last Post: 04-10-2004, 02:57 PM
  5. API "Clean Up" Functions & delete Pointers :: Winsock
    By kuphryn in forum Windows Programming
    Replies: 2
    Last Post: 05-10-2002, 06:53 PM