I wrote this program that get words from user and if it was entered already it will print you loose
but when I the first code crashs but the second code works! why the first code is crashs?

#include <stdio.h>
#include <string.h>
int getword(char *word);
int find(char * words[], int i);
char *words[100];

int main()
{

    int i = 0;
    while (i < 100)
    {
        printf("enter your word");
        get_word(words[i]);
        if (find(words, i))
        {
            printf("you lose");
            exit(1);
        }
        i++;
    }
    printf("no body wins");
}


int get_word(char *word)
{
    word= (char *)malloc(sizeof(char)*100);
    scanf("%s", word);
}

int find(char * words[],int i)
{
    int index = 0;

    while (index < i)
    {
        if (!strcmp(words[index++], words[i]))
            return 1;

    }
    return 0;
}





#include <stdio.h>
#include <string.h>
int getword(char *words[], int i);
int find(char * words[], int i);
char *words[100];

int main()
{

    int i = 0;
    while (i < 100)
    {
        printf("enter your word");
        get_word(words, i);
        //printf("hi%s", words[0]);
        if (find(words, i))
        {
            printf("you lose");
            exit(1);
        }
        i++;
    }
    printf("no body wins");
}


int get_word(char *words[], int i)
{
    words[i] = (char *)malloc(sizeof(char)* 100);
    scanf("%s", words[i]);
}

int find(char * words[], int i)
{
    int index = 0;

    while (index < i)
    {
        if (!strcmp(words[index++], words[i]))
            return 1;

    }
    return 0;
}

The diff:

get_word(words[i]);
get_word(words, i);



     int get_word(char *word)
    {
        word= (char *)malloc(sizeof(char)*100);
        scanf("%s", word);
    }


    int get_word(char *words[], int i)
    {
        words[i] = (char *)malloc(sizeof(char)* 100);
        scanf("%s", words[i]);
    }

word= (char )malloc(sizeof(char)100);

word is a completely separate and independent entity from words[i]. Essentially what you're doing here is creating a new pointer, allocating memory to it, then throwing it away (along with losing your only reference to the allocated memory).

words[i] = (char )malloc(sizeof(char) 100);

Here you're still creating a new pointer, but not trying to overwrite it. Instead, you're dereferencing it to get to the original location and overwriting that. This works because the temporary pointer isn't your only reference to the allocated memory.

You may also like to see this:

(that attempts to salvage your 'get_word' function ...
and then to add some extras)

/* get_word.c */


#define MAX_LEN_STR "255"
#define MAX_LEN 255

#define NUM_WORDS 3

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


#ifndef dwMYASSERT
#define dwMYASSERT
void myAssert( int condition, const char* msg )
{
    if( !condition )
    {
        fprintf( stderr, "%s\n", msg );
        fputs( "Press 'Enter' to exit program ... ", stderr );
        getchar();
        exit(1);
    }
}
#endif

#ifndef dwMY_STRLEN
#define dwMY_STRLEN
size_t my_strlen( const char* str )
{
    if( str ) return strlen(str);
    return 0;
}
#endif

#ifndef dwNEWMEMORY
#define dwNEWMEMORY
char* newMem( int bytes )
{
    char* n = (char*) malloc( bytes ); /* cast (in case) C++ compiler */
    myAssert( (n != NULL), "Error: malloc failed in 'newMem' ... " );
    return n;
}
#endif

#ifndef dwNEWCOPY
#define dwNEWCOPY
char* newCopy( const char* str )
{
    char* n = newMem( (my_strlen(str) + 1)*sizeof(char) ); /* cast for C++ compilers */
    strcpy( n, str );
    return n;
}
#endif


#ifndef dwNEWFGETSFIXED
#define dwNEWFGETSFIXED
char* newFgetsFixed( FILE* fin )
{
    char buf[MAX_LEN+1];

    if( fgets( buf, sizeof(buf), fin ) )
    {
        char *p = strchr( buf, '\n' ), c ;
        if( p ) *p = 0; /* strip off '\n' at end ... IF it exists */
        else while( (c = fgetc( fin )) != '\n'  &&  c != EOF ) ; /* flush... */
        return newCopy( buf );
    }
    else return NULL;
}
#endif

#ifndef dwGETWORD
#define dwGETWORD
char* getWord( FILE* fin )
{
    char buf[MAX_LEN+1];

    if( fscanf( fin, "%" MAX_LEN_STR "s", buf ) == 1 )
    {
        return newCopy( buf );
    }
    else return NULL;
}
#endif


char* get_word( char** word );



int main()
{
    char* words[NUM_WORDS];
    int i = 0;

    puts( "Demo 'get_word' \n" );

    while( i < NUM_WORDS )
    {
        printf("Enter word %d of %d: ", (i+1), NUM_WORDS );
        get_word( &words[i] );
        ++ i ;
    }
    for( i = 0;  i < NUM_WORDS; ++ i )
    {
        printf( "Word %d was: %s\n", (i+1), words[i] );
        free( words[i] );
    }


    while( getchar() != '\n' ) ; /* flush stdin .... */
    puts( "\nDemo 'getWord' \n" );

    i = 0;
    while( i < NUM_WORDS )
    {
        printf("Enter word %d of %d: ", (i+1), NUM_WORDS );
        if( (words[i] = getWord( stdin )) )
            ++ i ;
        else break;
    }
    for( i = 0;  i < NUM_WORDS; ++ i )
    {
        printf( "Word %d was: %s\n", (i+1), words[i] );
        free( words[i] );
    }


    while( getchar() != '\n' ) ; /* flush stdin .... */
    puts( "\nDemo 'newFgetsFixed' \n" );

    i = 0;
    while( i < NUM_WORDS )
    {
        printf("Enter LINE %d of %d: ", (i+1), NUM_WORDS );
        if( (words[i] = newFgetsFixed( stdin )) )
            ++ i ;
    }
    for( i = 0;  i < NUM_WORDS; ++ i )
    {
        printf( "LINE %d was: %s\n", (i+1), words[i] );
        free( words[i] );
    }


    return 0;
}


char* get_word( char** word )
{
    char buf[MAX_LEN+1];
    if( scanf( "%"MAX_LEN_STR "s", buf ) == 1 )
    {
        *word = newCopy( buf ); /* 'right size' copy ... */
        return *word;
    }
    /*  else ... */
    return NULL;
}

You may also find these following C utilities helpful when coding with dynamic C strings and/or dynamic arrays of C struct:

takeIns.h is at:
http://developers-heaven.net/forum/index.php/topic,2608.msg3157.html#msg3157

readLine.h is at:
http://developers-heaven.net/forum/index.php/topic,2580.msg2864.html#msg2864

Cvec.h
http://developers-heaven.net/forum/index.php/topic,2580.msg2862.html#msg2862

Here is a little demo program:

/* demo_takeIns.h.c */

/*
takeIns.h
    http://developers-heaven.net/forum/index.php/topic,2608.msg3157.html#msg3157

readLine.h
    http://developers-heaven.net/forum/index.php/topic,2580.msg2864.html#msg2864

Cvec.h
  http://developers-heaven.net/forum/index.php/topic,2580.msg2862.html#msg2862
*/

#include "takeIns.h"  /* includes "readLine.h" */


/* BEFORE including "Cvec.h", as per below, NEED to define these next two: */
typedef struct
{
    char* str;

} Rec; /* Note: Cvec NEEDS Rec pre-defined ... for it to work ok ...  */
void freeVrec( Rec* pRec )
{
    free( pRec->str ); /* need this since WILL BE using dynamic memory in Rec above */
}


/* NOW can include ... */
#include "Cvec.h"

void print( const Cvec* cv )
{
    int i = 0;
    for( ; i < cv->size; ++ i )
        printf( "line %d was : %s\n", (i+1), cv->ary[i].str );
}

int main()
{
    Cvec cv;
    initCvec( &cv ); /* MUST init to work ok */
    do
    {
        Rec rc;
        rc.str = takeInStr( "Enter a line of text: " );

        printf( "You entered %s\n", rc.str );
        if( tolower(takeInChr( "Is that ok to accept (y/n) ?" )) == 'y' )
        {
            push_backCvec( &cv, &rc );
            puts( "Was accepted ... " );
        }
        else
        {
            puts( "Was NOT accepted... " );
            free( rc.str );
        }
    }
    while( more() );

    print( &cv );
    printf( "Now cv.size = %d, cv.cap = %d\n", cv.size, cv.cap );

    clearCvec( &cv );

    printf( "Now cv.size = %d, cv.cap = %d\n", cv.size, cv.cap );
    return 0;
}

Edited 1 Year Ago by David W

This article has been dead for over six months. Start a new discussion instead.