7 Replies - 6647 Views - Last Post: 28 February 2009 - 07:48 PM Rate Topic: -----

#1 MikeAbyss  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 11
  • View blog
  • Posts: 56
  • Joined: 09-July 07

Passing an array of pointers by reference

Posted 27 February 2009 - 06:34 PM

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

#define totalWords 100

/* Function Prototype */
void print( char *word[], const int *size );
void getWords( char *word[], int *size );

/*	Main function, used to call other functions
	Input: N/A
	Output: N/A
*/
int main()
{
	char *wordPtr[totalWords]; // Used to post to the word
	int size = 0;

	getWords( wordPtr, &size );
	print( wordPtr, &size );

	getchar();
	return 0;
}
/*	Printing function
	Input: Takes in char array of pointers, and the max size of array
	Output: Displays the contents of  the array
*/
void print( char *word[], const int *size )
{
	
	int counter; // Used for loop

	for ( counter = 0; counter < *size; ++counter )
	{
		printf( "%s\n", word[counter] ); // Print out the contents of the pointer array
	}

}
/*	Tokenize the sentence
	Input: Takes in char array of pointers, and the size to change accordingly
	Output: Does not display anything
*/
void getWords( char *word[], int *size )
{
	char sentence[250]; // Used to hold one sentence, why 250 though?
	char *stringPtr = sentence; // Pointer to the sentence
	gets( sentence ); // gets each sentence

	stringPtr = strtok( stringPtr, " ,.;-" ); // string tokenization
	word[*size] = stringPtr; //Assigngs first letter to word
	(*size)++; // increment size by one

	while ( stringPtr != NULL ) // Loops through for the rest of the sentences until null
	{
		stringPtr = strtok( NULL, " ,.;-" );
		word[*size] = stringPtr;
		(*size)++;
	} 

}




After a long lecture I learned something pretty useful, which was an array of pointers, I'm trying to implement this into my program, but since it is my first time I get a few mistakes.

But anyways, my problem here is that I'm trying to pass an array of pointers, change the pointer address and then pass it by (by reference) I tried it a few times but I got confused by all the asterisk! Haha still new at this as you can all see :)

Thanks in advance for the help! Much appreciated :)

This post has been edited by MikeAbyss: 27 February 2009 - 06:49 PM


Is This A Good Question/Topic? 0
  • +

Replies To: Passing an array of pointers by reference

#2 JackOfAllTrades  Icon User is offline

  • Saucy!
  • member icon

Reputation: 6091
  • View blog
  • Posts: 23,606
  • Joined: 23-August 08

Re: Passing an array of pointers by reference

Posted 27 February 2009 - 07:18 PM

There's a problem here:
while ( stringPtr != NULL ) // Loops through for the rest of the sentences until null
{
    stringPtr = strtok( NULL, " ,.;-" );
    word[*size] = stringPtr;
    (*size)++;
}


The last time through stringPtr is not NULL at the start of the loop, but becomes NULL at the strtok. This results in the last entry of the word array to be a NULL pointer, and when dereferenced in the print function causes a segmentation fault/access violation.

I would do the strtok and the check at the same time instead:
while ((stringPtr = strtok( NULL, " ,.;-" ))!= NULL ) // Loops through for the rest of the sentences until null
{
   word[*size] = stringPtr;
   (*size)++;
}



Also, you're returning pointers to a memory structure which has gone out of scope, as sentence lives on the stack within the getWords function. Once you leave that function, there's no guarantee that the pointers point to valid memory any longer. You should declare sentence as static in this case, resulting in the memory for the sentence array being created at startup and present throughout the duration of the program.

And you shouldn't use gets() ;)
Was This Post Helpful? 0
  • +
  • -

#3 MikeAbyss  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 11
  • View blog
  • Posts: 56
  • Joined: 09-July 07

Re: Passing an array of pointers by reference

Posted 27 February 2009 - 09:20 PM

Thanks for the help! I shouldn't use gets? :o Is there a reason why? and if so what do you recommend instead?
Was This Post Helpful? 0
  • +
  • -

#4 David W  Icon User is offline

  • DIC supporter
  • member icon

Reputation: 281
  • View blog
  • Posts: 1,788
  • Joined: 20-September 08

Re: Passing an array of pointers by reference

Posted 28 February 2009 - 02:15 AM

You might like to use something like this ...

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

#define MAX 100

int getLineAndParse( char *words[] );
void printWords( char *words[], int num );
void freeWords( char *words[], int num );


int main()
{
    char *words[MAX]; /* reserve memory for a ragged char array of 'MAX' words */
    int num;
    printf("Enter a line of text to parse ...\n");
    num = getLineAndParse( words );
    printWords( words, num );

    freeWords( words, num );
    printf("\nPress 'Enter' to continue ... ");
    getchar();
    return 0;
}


int getLineAndParse( char *words[] )
{
    int len, num = 0;
    char *p, *q, sentence[1024]; /* make this as big as you need ...*/
    fgets( sentence, 1024, stdin  );
    p = strtok( sentence, " ,.;:-\n" );
    
    while(p != NULL)
    {
        len = strlen(p);
        q = (char*) malloc( len+1 );
        strcpy(q, p);
        words[num++] = q; /* copy pointer into array ... */
        
        p = strtok( NULL, " ,.;:-\n" );
    }
    return num;
}

void printWords( char *words[], int num )
{
    int i;
    for(i = 0; i < num; ++i ) printf("%s\n", words[i]);
}

void freeWords( char *words[], int num )
{
    int i;
    for( i = num-1; i >=0; --i ) free(words[i]);
}



http://en.wikipedia.org/wiki/Fgets

http://en.wikipedia.org/wiki/Gets
Was This Post Helpful? 0
  • +
  • -

#5 David W  Icon User is offline

  • DIC supporter
  • member icon

Reputation: 281
  • View blog
  • Posts: 1,788
  • Joined: 20-September 08

Re: Passing an array of pointers by reference

Posted 28 February 2009 - 03:50 AM

Or this ... 'safegets' ...

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

#define MAX 100

int getLineAndParse( char *words[] );
void printWords( char *words[], int num );
void freeWords( char *words[], int num );

/* Reads line up to buflen-1 char's ... Flushes
   the rest of the line, if it's not read.
   Does NOT include the '\n' char that
   fgets sometimes does ... */
char *safegets(char *s, int buflen)
{
    if(buflen < 1)
        return NULL;
    
    int i, k = getchar();

    /* Return NULL if no input is available */
    if(k == EOF)
        return NULL;

    s[0] = '\0'; /* Null-terminate as we go */

    /* Read and store characters until reaching a newline or end-of-file */
    for(i = 0; k != EOF && k != '\n'; ++i)
    {
        if(i < buflen-1)
        {
            s[i] = k;
            s[i+1] = '\0'; /* Null-terminate as we go */
        }
        k = getchar();

        /* If a read error occurs, the resulting buffer is not usable. */
        if(k == EOF && !feof(stdin))
            return NULL;
    }
    
    return s;
}


int main()
{
    char *words[MAX]; /* reserve memory for a ragged char array of 'MAX' words */
    int num;
    printf("Enter a line of text to parse ...\n");
    num = getLineAndParse( words );
    printWords( words, num );

    freeWords( words, num );
    printf("\nPress 'Enter' to continue ... ");
    getchar();
    return 0;
}


int getLineAndParse( char *words[] )
{
    int len, num = 0;
    char *p, *q, sentence[1024]; /* make this as big as you need ...*/
    //fgets( sentence, 1024, stdin  );
    if( safegets(sentence, 1024) == NULL )
        return 0;
        
    p = strtok( sentence, " ,.;:-" );
    
    while(p != NULL)
    {
        len = strlen(p);
        q = (char*) malloc( len+1 );
        strcpy(q, p);
        words[num++] = q; /* copy pointer into array ... */
        
        p = strtok( NULL, " ,.;:-" );
    }
    return num;
}

void printWords( char *words[], int num )
{
    int i;
    for(i = 0; i < num; ++i ) printf("%s\n", words[i]);
}

void freeWords( char *words[], int num )
{
    int i;
    for( i = num-1; i >=0; --i ) free(words[i]);
}

This post has been edited by David W: 28 February 2009 - 03:54 AM

Was This Post Helpful? 0
  • +
  • -

#6 David W  Icon User is offline

  • DIC supporter
  • member icon

Reputation: 281
  • View blog
  • Posts: 1,788
  • Joined: 20-September 08

Re: Passing an array of pointers by reference

Posted 28 February 2009 - 05:17 AM

Or this ... with readLine()

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

#define MAX 100

int getLineAndParse( char *words[] );
void printWords( char *words[], int num );
void freeWords( char *words[], int num );

/* Reads lines of any length ...
   Does NOT include the '\n' char that fgets does */
char *readLine()
{
    char *s;
    int bufsize = 1024, c, i = 0;
    
    /* Return NULL if no input is available */
    if((c=getchar()) == EOF) return NULL;

    s = (char*) calloc( bufsize, sizeof(char) );

    /* Read and store characters until reaching a newline or end-of-file */
    while( c != EOF && c != '\n' )
    {
        if( i == bufsize-1 ) /* then get some more memory */
        {
            bufsize += 1024;
            (char*) realloc(s, bufsize*sizeof(char));
        }
        
        s[i++] = c;
        c = getchar();

        /* If a read error occurs, the resulting buffer is not usable. */
        if(c == EOF && !feof(stdin))
        {   free(s);
            return NULL;
        }
    }
    
    s[i] = '\0'; /* Null-terminate */
    
    return realloc(s, i); /* now resize ... to just fit */
}


int main()
{
    char *words[MAX]; /* reserve memory for a ragged char array of 'MAX' words */
    int num;
    printf("Enter a line of text to parse ...\n");
    num = getLineAndParse( words );
    printWords( words, num );

    freeWords( words, num );
    printf("\nPress 'Enter' to continue ... ");
    getchar();
    return 0;
}


int getLineAndParse( char *words[] )
{
    int len, num = 0;
    char *p, *q, *s;
    if( (s=readLine()) == NULL )
        return 0;
        
    p = strtok( s, " ,.;:-" );
    
    while(p != NULL)
    {
        len = strlen(p);
        q = (char*) malloc( len+1 );
        strcpy(q, p);
        words[num++] = q; /* copy pointer into array of pointers */
        
        p = strtok( NULL, " ,.;:-" );
    }
    free(s);
    return num;
}

void printWords( char *words[], int num )
{
    int i;
    for(i = 0; i < num; ++i ) printf("%s\n", words[i]);
}

void freeWords( char *words[], int num )
{
    int i;
    for( i = num-1; i >=0; --i ) free(words[i]);
}

Was This Post Helpful? 1
  • +
  • -

#7 MikeAbyss  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 11
  • View blog
  • Posts: 56
  • Joined: 09-July 07

Re: Passing an array of pointers by reference

Posted 28 February 2009 - 01:52 PM

David W, Thank-you so much for the code you have provided, they helped me get over the "hump" I was having in my assignment :)
Was This Post Helpful? 0
  • +
  • -

#8 David W  Icon User is offline

  • DIC supporter
  • member icon

Reputation: 281
  • View blog
  • Posts: 1,788
  • Joined: 20-September 08

Re: Passing an array of pointers by reference

Posted 28 February 2009 - 07:48 PM

View PostMikeAbyss, on 28 Feb, 2009 - 12:52 PM, said:

David W, Thank-you so much for the code you have provided, they helped me get over the "hump" I was having in my assignment :)

Shalom Michael,

You are very welcome ...

I'm in the process of putting together some example code for a free e-text for Beginners in Computer Programming (the next version is to be for C/C++) ...

This is what I have up ... to-date ... Please take a look if you like.

http://developers-he...index.php/topic,46.0.html
http://developers-he.../index.p...opic,106.0.html

Shalom,
David

This post has been edited by David W: 01 March 2009 - 01:50 AM

Was This Post Helpful? 0
  • +
  • -

Page 1 of 1