473,385 Members | 1,483 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,385 software developers and data experts.

an example code of TPOP(the practice of programming),why cannot lookup

this code is an example code of TPOP, i type them and can be
compiled...
but when give some input , it getting segment fault ....
i observed that when the build() initial the word table ... it invoke
next_word(in the book its name is new() )and invoke the routine
lookup ...but it cannot lookup anything ....and return NULL.

where goes wrong?

below is the code...

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#define NPREF 2
#define NHASH 4093
#define MAXGEN 10000
struct Suffix {
char *word;
struct Suffix *next;
};

struct State {
char *pref[NPREF];
struct Suffix *suf;
struct State * next;
};
typedef struct State *state_ptr;
typedef struct State state;
typedef struct Suffix suffix;
typedef suffix * suffix_ptr;

state *statetab[NHASH];
char NOWORD[] = "\n"; /* cannot appear as real word */
/* hash: compute hash value for array of NPREF strings */
const int MULTIP = 31; /* for hash() */
void next_word(char *prefix[NPREF], char *suffix);
void addsuffix (state_ptr sp, char *suffix);
unsigned int
hash(char *s[NPREF])
{
unsigned int h;
unsigned char *str;
int i ;

for (i = 0;i < NPREF; i++)
{

for (str =(unsigned char *)s[i];*str != '\0' ; str++)
h = h * MULTIP + (*str);

}
return h % NHASH;
}
/* lookup: search for prefix ; create if requested */
/* returns pointer if present or created ; NULL if not.
* creation doesn't strdup so string mustn't change later.*/

state_ptr
lookup(char * prefix[NPREF], int create)
{
state_ptr sp;
int h = hash(prefix);
int i;
for (sp = statetab[h]; sp != NULL ; sp = sp->next) {
for ( i=0; i< NPREF; i++)
if (strcmp(prefix[i], statetab[h]->pref[i]) !=0)
break;
if (i == NPREF) /* we found it */
return sp;
}
if (create) {
sp = (state_ptr)malloc(sizeof(state));
for (i = 0; i < NPREF; i++)
sp->pref[i] = prefix[i];
sp->suf = NULL;
sp->next = statetab[h];
statetab[h] = sp;
}
return sp;

}

char *
estrdup(char s[])
{
register char *t;

if (NULL == (t = malloc(strlen(s)+1))) {
return(NULL);
}
strcpy(t, s);
return(t);
}

/* build: read input , build prefix table */
void
build (char *prefix[NPREF],FILE *f)
{
char buf[100], fmt[10];
/* create a dymatic format of fscanf */
sprintf(fmt,"%%%ds",sizeof(buf)-1);

while ( fscanf( f, fmt, buf ) != EOF)
next_word (prefix, (char *)estrdup(buf)); /* eatrdup is get a
duplacat buf */

}
/* next_word: add word to suffix list , update prefix */
void
next_word(char *prefix[NPREF], char *suffix)
{
state_ptr sp ;
sp = lookup (prefix, 1); /* create if not find */
addsuffix(sp, suffix);
memmove(prefix, prefix+1, (NPREF-1)*sizeof (prefix[0]));
prefix[NPREF-1] = suffix;

}

/* addsuffix: add to state, suffix must not change later. */
void
addsuffix (state_ptr sp, char *suffix)
{
suffix_ptr sfp;
sfp= (suffix_ptr) malloc( sizeof (suffix));
sfp->word = suffix;
sfp->next = sp->suf;
sp->suf = sfp;
/* smart manipulate of pointer */

}
/* generate: produce output , one word pre line. */
void
generate( int nwords )
{
state_ptr sp;
char *prefix[NPREF], *w;
suffix *suf;
int i , nmatch;

/* reset initial prefix */
for (i = 0 ; i < NPREF; i++)
prefix[i] = NOWORD;

/* main loop */
for (i = 0; i < nwords; i++) {
sp = lookup(prefix, 0);
nmatch = 0;
if (sp == NULL)
fprintf(stderr,"internal error: lookup failed");
for (suf = sp->suf; suf != NULL; suf = suf->next)
if (rand() % ++nmatch == 0)
if (suf->word != NULL)
w = suf->word;
if (strcmp (w, NOWORD) == 0)
break;
printf("%s\n", w);

memmove(prefix , prefix+1, (NPREF-1)*sizeof(prefix[0]));
prefix [NPREF-1] = w;
}
}
int main(void)
{
int i, nwords = MAXGEN;
char *prefix[NPREF]; /* current input prefix */

int c;
long seed;
seed = time(NULL);

srand(seed);
for (i = 0; i < NPREF; i++) /* set up initial prefix */
prefix[i] = NOWORD;
build(prefix, stdin);
next_word(prefix, NOWORD);
generate(nwords);
return 0;
}

Apr 20 '07 #1
2 1746
On 20 Apr 2007 09:19:32 -0700, anson <kz****@gmail.comwrote:
>this code is an example code of TPOP, i type them and can be
compiled...
but when give some input , it getting segment fault ....
I don't get a seg fault but you have some undefined behavior in your
code.
>i observed that when the build() initial the word table ... it invoke
next_word(in the book its name is new() )and invoke the routine
lookup ...but it cannot lookup anything ....and return NULL.

where goes wrong?

below is the code...

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#define NPREF 2
#define NHASH 4093
#define MAXGEN 10000
struct Suffix {
char *word;
struct Suffix *next;
};

struct State {
char *pref[NPREF];
struct Suffix *suf;
struct State * next;
};
typedef struct State *state_ptr;
typedef struct State state;
typedef struct Suffix suffix;
typedef suffix * suffix_ptr;

state *statetab[NHASH];
char NOWORD[] = "\n"; /* cannot appear as real word */
/* hash: compute hash value for array of NPREF strings */
const int MULTIP = 31; /* for hash() */
void next_word(char *prefix[NPREF], char *suffix);
void addsuffix (state_ptr sp, char *suffix);
unsigned int
hash(char *s[NPREF])
{
unsigned int h;
unsigned char *str;
int i ;

for (i = 0;i < NPREF; i++)
{

for (str =(unsigned char *)s[i];*str != '\0' ; str++)
h = h * MULTIP + (*str);
This invokes undefined behavior because the h on the right side of the
= operator has not been given a value.
>
}
return h % NHASH;
}
/* lookup: search for prefix ; create if requested */
/* returns pointer if present or created ; NULL if not.
* creation doesn't strdup so string mustn't change later.*/

state_ptr
lookup(char * prefix[NPREF], int create)
{
state_ptr sp;
int h = hash(prefix);
Possible undefined behavior. hash() returns an unsigned int and that
value may not fit in the int h.
> int i;
for (sp = statetab[h]; sp != NULL ; sp = sp->next) {
for ( i=0; i< NPREF; i++)
if (strcmp(prefix[i], statetab[h]->pref[i]) !=0)
break;
if (i == NPREF) /* we found it */
return sp;
}
if (create) {
sp = (state_ptr)malloc(sizeof(state));
for (i = 0; i < NPREF; i++)
sp->pref[i] = prefix[i];
sp->suf = NULL;
sp->next = statetab[h];
statetab[h] = sp;
}
return sp;

}

char *
estrdup(char s[])
{
register char *t;

if (NULL == (t = malloc(strlen(s)+1))) {
return(NULL);
}
strcpy(t, s);
return(t);
}

/* build: read input , build prefix table */
void
build (char *prefix[NPREF],FILE *f)
{
char buf[100], fmt[10];
/* create a dymatic format of fscanf */
sprintf(fmt,"%%%ds",sizeof(buf)-1);
Possible undefined behavior. %d promises sprintf that the
corresponding argument is an int. sizeof evaluates to a size_t which
could be a different integer type.
>
while ( fscanf( f, fmt, buf ) != EOF)
next_word (prefix, (char *)estrdup(buf)); /* eatrdup is get a
duplacat buf */
The cast is meaningless since the return from estrdup() is already a
char*.
>
}
/* next_word: add word to suffix list , update prefix */
void
next_word(char *prefix[NPREF], char *suffix)
{
state_ptr sp ;
sp = lookup (prefix, 1); /* create if not find */
addsuffix(sp, suffix);
memmove(prefix, prefix+1, (NPREF-1)*sizeof (prefix[0]));
prefix[NPREF-1] = suffix;

}

/* addsuffix: add to state, suffix must not change later. */
void
addsuffix (state_ptr sp, char *suffix)
{
suffix_ptr sfp;
sfp= (suffix_ptr) malloc( sizeof (suffix));
Don't cast the return from malloc. It cannot help and is unnecessary
since you #include stdlib.h However, you do need to test the return
value to insure malloc succeeded before you attempt to access the
memory requested.
> sfp->word = suffix;
sfp->next = sp->suf;
sp->suf = sfp;
/* smart manipulate of pointer */

}
/* generate: produce output , one word pre line. */
void
generate( int nwords )
{
state_ptr sp;
char *prefix[NPREF], *w;
suffix *suf;
int i , nmatch;

/* reset initial prefix */
for (i = 0 ; i < NPREF; i++)
prefix[i] = NOWORD;

/* main loop */
for (i = 0; i < nwords; i++) {
sp = lookup(prefix, 0);
nmatch = 0;
if (sp == NULL)
fprintf(stderr,"internal error: lookup failed");
for (suf = sp->suf; suf != NULL; suf = suf->next)
if (rand() % ++nmatch == 0)
if (suf->word != NULL)
w = suf->word;
if (strcmp (w, NOWORD) == 0)
break;
printf("%s\n", w);

memmove(prefix , prefix+1, (NPREF-1)*sizeof(prefix[0]));
prefix [NPREF-1] = w;
}
}
int main(void)
{
int i, nwords = MAXGEN;
char *prefix[NPREF]; /* current input prefix */

int c;
long seed;
seed = time(NULL);

srand(seed);
for (i = 0; i < NPREF; i++) /* set up initial prefix */
prefix[i] = NOWORD;
build(prefix, stdin);
next_word(prefix, NOWORD);
generate(nwords);
return 0;
}

Remove del for email
Apr 29 '07 #2
On Sat, 28 Apr 2007 17:42:40 -0700, Barry Schwarz <sc******@doezl.net>
wrote:
On 20 Apr 2007 09:19:32 -0700, anson <kz****@gmail.comwrote:
this code is an example code of TPOP, i type them and can be
compiled...
but when give some input , it getting segment fault ....

I don't get a seg fault but you have some undefined behavior in your
code.
<snip mostly good comments>
int h = hash(prefix);

Possible undefined behavior. hash() returns an unsigned int and that
value may not fit in the int h.
In C99 not actually UB; instead either an implementation-defined
conversion or an implementation-defined signal is raised. This is
still unportable, but not the full evil of UB.

sprintf(fmt,"%%%ds",sizeof(buf)-1);

Possible undefined behavior. %d promises sprintf that the
corresponding argument is an int. sizeof evaluates to a size_t which
could be a different integer type.
s/could/must/ as size_t must be unsigned and %d expects signed.
However, if size_t happens to be unsigned int it _probably_ works. For
a user-written vararg function, substituting for a signed int an
unsigned int with a value in the range of signed int -- and here the
value is 99 which is portably within range -- is guaranteed. There is
no explicit provision this works for non-user-written sprintf, but
generally it uses the same mechanism(s) and does.

OTOH size_t can be an unsigned type other than (and larger than)
unsigned int, and then it probably won't work and is definitely UB.

- formerly david.thompson1 || achar(64) || worldnet.att.net
May 21 '07 #3

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: ccs | last post by:
The compile error is: error C2059: syntax error : 'constant'. Since CEngine does have a constructor taking three parameters. class CEngine { public: CEngine(int a, int b, int c) {} };
2
by: Chaokai Ching | last post by:
//--------------------------------------------------------------------------- // Matrix.h //--------------------------------------------------------------------------- #if !defined(Matrix_H) ...
4
by: Dave | last post by:
Greetings, I have a web application that will be hosted on our intranet. I would like to determine, via code the user's windows login name and domain in the following format: DOMAIN\loginname...
0
by: chrislearner | last post by:
Hi All, I am new to this group and urgently require help from you guys!! I have to hard code the START date and the END date to 04/01/2006 and 06/30/2006 respectively. Here's the existing sql...
1
momotaro
by: momotaro | last post by:
looking for some one to code the Chudnovsky Brothers Formula!
2
by: polocar | last post by:
Hi all, I'm writing a C# program, and I was wondering: is there a way to raise by code the click event of a Button control, as if it was the user to have clicked on it? Thank you very much
3
by: segecko | last post by:
Hi I have a created a custom usercontrol which inherites an Excel like usercontrol. In this usercontrol I have a custom property called SpreadTemplate, which is an enum with (at the moment) two...
5
by: bb nicole | last post by:
Below is the list menu of search engine.. How to code if i want to put <option selected>ALL</option> Interface <tr> <td>Job Category:</td> <td><select name="jobCategory"> ...
2
by: raylopez99 | last post by:
Beware newbies: I spent a day before I figured this out: copying a bitmap (image) file to file is not quite like copying a text file--you have to do some tricks (see below), like using a...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.