Compile Time Error ... arghh

F

Finger.Octopus

I dont know whats terribly going wrong with this, well I know there's
some memory allocation with this but I tried hard to fix it and when
it gets fixed it doesn't shows up the desired value, this is the code
that shows the compile-time error:

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

#define $WORD_LIST(X) "resource/" X

typedef struct char_type
{
char** ptr;
}ccarray;

int ccarray_create(ccarray *c)
{
c = (ccarray*)malloc(sizeof(ccarray*));

c->ptr = (char**) malloc(sizeof(char**) * 1024);
return 0;
}

int ccarray_insert(ccarray *c, char* str, int pos)
{
c->ptr[pos] = str;
printf("%d %s\n", pos, c->ptr[pos]);
}

int ccarray_destroy(ccarray *c)
{
free( c->ptr );
free( c );
return 0;
}

int ccarray_read_file(ccarray* c, char* filename)
{
FILE * fptr;
char* line;
int i;

fptr = fopen(filename, "r");
line = (char*) malloc(sizeof(char)*100);
i = 0;

while( fscanf(fptr,"%s",line) != EOF )
{
ccarray_insert(c, line, i);
i++;
}
free(line);
fclose(fptr);
}

int ccarray_print(ccarray* c)
{
int i = 0;
while ( c->ptr != NULL )
{
printf("Line: %s\n", c->ptr );
i++;
}
}

int main()
{
ccarray * c;
ccarray_create(c);
ccarray_read_file(c, $WORD_LIST("sample.txt"));
ccarray_print(c);
ccarray_destroy(c);
return 0;
}

.... and this thing runs fine but doesn't shows any result:

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

#define $WORD_LIST(X) "resource/" X

typedef struct char_type
{
char** ptr;
}ccarray;

int ccarray_create(ccarray **c)
{
(*c) = (ccarray*)malloc(sizeof(ccarray));
(*c) = (ccarray*)malloc(sizeof(ccarray));
(*c)->ptr = (char**) malloc(sizeof(char**) * 1024);
return 0;
}

int ccarray_insert(ccarray **c, char* str, int pos)
{
(*c)->ptr[pos] = str;
//printf("%s ", (*c)->ptr[pos] );
}

int ccarray_destroy(ccarray **c)
{
free( (*c)->ptr );
free( c );
return 0;
}

int ccarray_read_file(ccarray** c, char* filename)
{
FILE * fptr;
char* line;
int i;

fptr = fopen(filename, "r");
line = (char*) malloc(sizeof(char)*100);
i = 0;

while( fscanf(fptr,"%s",line) != EOF )
{
ccarray_insert(c, line, i);
i++;
}
free(line);
fclose(fptr);
}

int ccarray_print(ccarray** c)
{
int i = 0;
while ( (*c)->ptr != NULL )
{
printf("Line: %s\n", (*c)->ptr );
i++;
}
}

int main()
{
ccarray * c;
ccarray_create(&c);
ccarray_read_file(&c, $WORD_LIST("sample.txt"));
ccarray_print(&c);
ccarray_destroy(&c);
return 0;
}
 
R

Richard Heathfield

(e-mail address removed) said:
I dont know whats terribly going wrong with this, well I know there's
some memory allocation with this but I tried hard to fix it and when
it gets fixed it doesn't shows up the desired value, this is the code
that shows the compile-time error:

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

#define $WORD_LIST(X) "resource/" X

Lose the $. If that doesn't do the trick, let us know.
 
F

Finger.Octopus

It has no concern with it, but still I removed it and it still doesn't
works.
 
R

Richard Heathfield

(e-mail address removed) said:
It has no concern with it, but still I removed it and it still doesn't
works.

foo.c:65: warning: `$' in identifier
foo.c:12: warning: no previous prototype for `ccarray_create'
foo.c: In function `ccarray_create':
foo.c:13: warning: implicit declaration of function `malloc'
foo.c:13: warning: cast does not match function type
foo.c:15: warning: cast does not match function type
foo.c: At top level:
foo.c:20: warning: no previous prototype for `ccarray_insert'
foo.c: In function `ccarray_insert':
foo.c:23: warning: control reaches end of non-void function
foo.c: At top level:
foo.c:26: warning: no previous prototype for `ccarray_destroy'
foo.c: In function `ccarray_destroy':
foo.c:27: warning: implicit declaration of function `free'
foo.c: At top level:
foo.c:33: warning: no previous prototype for `ccarray_read_file'
foo.c: In function `ccarray_read_file':
foo.c:39: warning: cast does not match function type
foo.c:49: warning: control reaches end of non-void function
foo.c: At top level:
foo.c:52: warning: no previous prototype for `ccarray_print'
foo.c: In function `ccarray_print':
foo.c:59: warning: control reaches end of non-void function
foo.c: At top level:
foo.c:62: warning: function declaration isn't a prototype
foo.c: In function `main':
foo.c:65: warning: passing arg 2 of `ccarray_read_file' discards
qualifiers from
pointer target type
foo.c:63: warning: `c' might be used uninitialized in this function

Losing the $ and adding <stdlib.h>, we get:

foo.c:13: warning: no previous prototype for `ccarray_create'
foo.c:21: warning: no previous prototype for `ccarray_insert'
foo.c: In function `ccarray_insert':
foo.c:24: warning: control reaches end of non-void function
foo.c: At top level:
foo.c:27: warning: no previous prototype for `ccarray_destroy'
foo.c:34: warning: no previous prototype for `ccarray_read_file'
foo.c: In function `ccarray_read_file':
foo.c:50: warning: control reaches end of non-void function
foo.c: At top level:
foo.c:53: warning: no previous prototype for `ccarray_print'
foo.c: In function `ccarray_print':
foo.c:60: warning: control reaches end of non-void function
foo.c: At top level:
foo.c:63: warning: function declaration isn't a prototype
foo.c: In function `main':
foo.c:66: warning: passing arg 2 of `ccarray_read_file' discards
qualifiers from pointer target type
foo.c:64: warning: `c' might be used uninitialized in this function

Adding full prototype info:

foo.c: In function `ccarray_insert':
foo.c:30: warning: control reaches end of non-void function
foo.c: In function `ccarray_read_file':
foo.c:56: warning: control reaches end of non-void function
foo.c: In function `ccarray_print':
foo.c:66: warning: control reaches end of non-void function
foo.c: In function `main':
foo.c:72: warning: passing arg 2 of `ccarray_read_file' discards
qualifiers from pointer target type
foo.c:70: warning: `c' might be used uninitialized in this function


And now we're getting to the real problem. c is indeed used
uninitialised - its (indeterminate) value is copied to ccarray_create.
ccarray_create changes its copy, but to no avail, since the
(indeterminate) value in main is unaffected.

When you want to change an object's value by passing it to a function,
you have to pass the address of that object. Passing the object's value
is pointless.
 
F

Finger.Octopus

(e-mail address removed) said:


foo.c:65: warning: `$' in identifier
foo.c:12: warning: no previous prototype for `ccarray_create'
foo.c: In function `ccarray_create':
foo.c:13: warning: implicit declaration of function `malloc'
foo.c:13: warning: cast does not match function type
foo.c:15: warning: cast does not match function type
foo.c: At top level:
foo.c:20: warning: no previous prototype for `ccarray_insert'
foo.c: In function `ccarray_insert':
foo.c:23: warning: control reaches end of non-void function
foo.c: At top level:
foo.c:26: warning: no previous prototype for `ccarray_destroy'
foo.c: In function `ccarray_destroy':
foo.c:27: warning: implicit declaration of function `free'
foo.c: At top level:
foo.c:33: warning: no previous prototype for `ccarray_read_file'
foo.c: In function `ccarray_read_file':
foo.c:39: warning: cast does not match function type
foo.c:49: warning: control reaches end of non-void function
foo.c: At top level:
foo.c:52: warning: no previous prototype for `ccarray_print'
foo.c: In function `ccarray_print':
foo.c:59: warning: control reaches end of non-void function
foo.c: At top level:
foo.c:62: warning: function declaration isn't a prototype
foo.c: In function `main':
foo.c:65: warning: passing arg 2 of `ccarray_read_file' discards
qualifiers from
pointer target type
foo.c:63: warning: `c' might be used uninitialized in this function

Losing the $ and adding <stdlib.h>, we get:

foo.c:13: warning: no previous prototype for `ccarray_create'
foo.c:21: warning: no previous prototype for `ccarray_insert'
foo.c: In function `ccarray_insert':
foo.c:24: warning: control reaches end of non-void function
foo.c: At top level:
foo.c:27: warning: no previous prototype for `ccarray_destroy'
foo.c:34: warning: no previous prototype for `ccarray_read_file'
foo.c: In function `ccarray_read_file':
foo.c:50: warning: control reaches end of non-void function
foo.c: At top level:
foo.c:53: warning: no previous prototype for `ccarray_print'
foo.c: In function `ccarray_print':
foo.c:60: warning: control reaches end of non-void function
foo.c: At top level:
foo.c:63: warning: function declaration isn't a prototype
foo.c: In function `main':
foo.c:66: warning: passing arg 2 of `ccarray_read_file' discards
qualifiers from pointer target type
foo.c:64: warning: `c' might be used uninitialized in this function

Adding full prototype info:

foo.c: In function `ccarray_insert':
foo.c:30: warning: control reaches end of non-void function
foo.c: In function `ccarray_read_file':
foo.c:56: warning: control reaches end of non-void function
foo.c: In function `ccarray_print':
foo.c:66: warning: control reaches end of non-void function
foo.c: In function `main':
foo.c:72: warning: passing arg 2 of `ccarray_read_file' discards
qualifiers from pointer target type
foo.c:70: warning: `c' might be used uninitialized in this function

And now we're getting to the real problem. c is indeed used
uninitialised - its (indeterminate) value is copied to ccarray_create.
ccarray_create changes its copy, but to no avail, since the
(indeterminate) value in main is unaffected.

When you want to change an object's value by passing it to a function,
you have to pass the address of that object. Passing the object's value
is pointless.


There are two programs above, which one are you talking about?
 
F

Finger.Octopus

After some changes, it runs fine but still it doesn't shows anything:

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

#define WORD_LIST(X) "resource/" X

typedef struct char_type
{
char** ptr;
}ccarray;

ccarray* ccarray_create()
{
ccarray* c = (ccarray*)malloc(sizeof(ccarray));
c->ptr = (char**) malloc(sizeof(char**) * 1024);
return c;
}

int ccarray_insert(ccarray *c, char* str, int pos)
{
c->ptr[pos] = str;
//printf("%s ", (*c)->ptr[pos] );
}

int ccarray_destroy(ccarray *c)
{
free( c->ptr );
free( c );
return 0;
}

int ccarray_read_file(ccarray* c, char* filename)
{
FILE * fptr;
char* line;
int i;

fptr = fopen(filename, "r");
line = (char*) malloc(sizeof(char)*100);
i = 0;

while( fscanf(fptr,"%s",line) != EOF )
{
ccarray_insert(c, line, i);
i++;
}
free(line);
fclose(fptr);
}

int ccarray_print(ccarray* c)
{
int i = 0;
while ( c->ptr != NULL )
{
printf("Line: %s\n", c->ptr );
i++;
}
}

int main()
{
ccarray * c = ccarray_create(c);
ccarray_read_file(c, WORD_LIST("sample.txt"));
ccarray_print(c);
ccarray_destroy(c);
return 0;
}
 
F

Finger.Octopus

The source file sample.txt contains:

EDIT
BLAH
WHATEVER

and, what I get in output of this program is :

Line:
Line:
Line:


It is getting the number of lines for a strange reason but not the
lines themselves.
 
R

Richard Heathfield

(e-mail address removed) said:
After some changes, it runs fine but still it doesn't shows anything:

For me, however, it doesn't compile. This is hardly surprising, since
you appear to have ignored some of my advice.

foo.c:12: warning: function declaration isn't a prototype
foo.c: In function `ccarray_create':
foo.c:13: warning: implicit declaration of function `malloc'
foo.c:13: warning: cast does not match function type
foo.c:14: warning: cast does not match function type
foo.c: At top level:
foo.c:19: warning: no previous prototype for `ccarray_insert'
foo.c: In function `ccarray_insert':
foo.c:21: parse error before `/'
foo.c:22: warning: control reaches end of non-void function
foo.c: At top level:
foo.c:25: warning: no previous prototype for `ccarray_destroy'
foo.c: In function `ccarray_destroy':
foo.c:26: warning: implicit declaration of function `free'
foo.c: At top level:
foo.c:32: warning: no previous prototype for `ccarray_read_file'
foo.c: In function `ccarray_read_file':
foo.c:38: warning: cast does not match function type
foo.c:48: warning: control reaches end of non-void function
foo.c: At top level:
foo.c:51: warning: no previous prototype for `ccarray_print'
foo.c: In function `ccarray_print':
foo.c:58: warning: control reaches end of non-void function
foo.c: At top level:
foo.c:61: warning: function declaration isn't a prototype
foo.c: In function `main':
foo.c:63: warning: passing arg 2 of `ccarray_read_file' discards
qualifiers from pointer target type
make: *** [foo.o] Error 1

To explain the changes I made, line by line, would be tedious. Note,
however, the significant differences between your program and mine, not
least amongst which is the fact that my version works.

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

#define WORD_LIST(X) "resource/" X
#define INIT_MAX_LINES 1024
#define INIT_LINE_LEN 100

typedef struct char_type
{
char **ptr;
size_t linecount;
size_t maxlines;
} ccarray;

ccarray *ccarray_create(void);
int ccarray_insert(ccarray * c, char *str, size_t pos);
int ccarray_destroy(ccarray * c);
int ccarray_read_file(ccarray * c, const char *filename);
int ccarray_print(ccarray * c);
char *dupstr(const char *s);

char *dupstr(const char *s)
{
size_t len = strlen(s) + 1;
char *new = malloc(len);
if(new != NULL)
{
memcpy(new, s, len);
}
return new;
}

ccarray *ccarray_create(void)
{
ccarray *c = malloc(sizeof *c);

if(c != NULL)
{
c->ptr = malloc(INIT_MAX_LINES * sizeof *c->ptr);
if(c->ptr == NULL)
{
free(c);
c = NULL;
}
else
{
size_t i = 0;
c->linecount = 0;
c->maxlines = INIT_MAX_LINES;
while(i < c->linecount)
{
c->ptr[i++] = NULL;
}
}
}
return c;
}

int ccarray_insert(ccarray * c, char *str, size_t pos)
{
int rc = 0;
if(pos >= c->maxlines)
{
size_t newsize = (c->maxlines * 2 > pos) ?
c->maxlines * 2 : (pos + 1);

char **tmp = realloc(c->ptr, newsize);
if(tmp == NULL)
{
rc = 1;
}
else
{
c->ptr = tmp;
c->maxlines = newsize;
}
}
if(rc == 0)
{
if(pos > c->linecount)
{
size_t i = c->linecount;
while(i < pos)
{
c->ptr[i++] = NULL;
}
c->linecount = pos + 1;
}
else if(pos == c->linecount)
{
++c->linecount;
}
c->ptr[pos] = dupstr(str);
if(c->ptr[pos] == NULL)
{
rc = 2;
}
}
return rc;
}

int ccarray_destroy(ccarray * c)
{
size_t i = 0;
while(i < c->linecount)
{
free(c->ptr[i++]);
}
free(c->ptr);
free(c);
return 0;
}

int ccarray_read_file(ccarray *c, const char *filename)
{
FILE *fptr;
char *line;
int i;
int rc = 0;

fptr = fopen(filename, "r");
if(fptr != NULL)
{
line = malloc(INIT_LINE_LEN);
if(line != NULL)
{
char safefmt[32] = {0};
i = 0;

sprintf(safefmt, "%%%ds", INIT_LINE_LEN - 1);
while(rc == 0 && fscanf(fptr, safefmt, line) == 1)
{
rc = ccarray_insert(c, line, i);
i++;
}

free(line);
}
else
{
rc = 4;
}
fclose(fptr);
}
else
{
rc = 3;
}
return rc;
}

int ccarray_print(ccarray * c)
{
int i = 0;

while(c->ptr != NULL)
{
printf("Line: %s\n", c->ptr);
i++;
}
return 0;
}

int main(void)
{
int rc = 0;
ccarray *c = ccarray_create();
if(c != NULL)
{
rc = ccarray_read_file(c, WORD_LIST("sample.txt"));
if(rc != 0)
{
fprintf(stderr, "read failed: %d\n", rc);
}
else
{
ccarray_print(c);
}
ccarray_destroy(c);
}
return 0;
}
 
B

Barry Schwarz

After some changes, it runs fine but still it doesn't shows anything:

How can it run fine if it doesn't do what you want.
#include <stdio.h>
#include <string.h>

You are missing stdlib.h. All your calls to malloc invoke undefined
behavior.
#define WORD_LIST(X) "resource/" X

typedef struct char_type
{
char** ptr;
}ccarray;

ccarray* ccarray_create()

If your function takes no arguments, you should specify that
ccarray* ccarray_create(void)
{
ccarray* c = (ccarray*)malloc(sizeof(ccarray));

Don't cast the return from malloc. It never helps. In this case, it
caused the compiler to suppress a mandatory diagnostic that would have
led you to include stdlib.h as noted above.
c->ptr = (char**) malloc(sizeof(char**) * 1024);

This is the wrong amount of space to allocate. c->ptr is a char**.
Therefore, the object it points to is a char*. If you want to
allocate space for 1024 char*, then you should code
sizeof(char*)*1024. However, rather than have to keep all the types
straight manually, the following will always yield the correct amount
of space
c->ptr = malloc(1024 * sizeof *c->ptr);
return c;
}

int ccarray_insert(ccarray *c, char* str, int pos)
{
c->ptr[pos] = str;
//printf("%s ", (*c)->ptr[pos] );

If this weren't a comment it would be a syntax error. c is a pointer
to struct. Therefore *c and (*c) are of type struct. You cannot use
the -> operator on a struct, only on a pointer to struct.
}

int ccarray_destroy(ccarray *c)
{
free( c->ptr );

You got it correct here.
free( c );
return 0;
}

int ccarray_read_file(ccarray* c, char* filename)
{
FILE * fptr;
char* line;
int i;

fptr = fopen(filename, "r");

Did fopen() really open the file? Shouldn't you check?
line = (char*) malloc(sizeof(char)*100);
i = 0;

while( fscanf(fptr,"%s",line) != EOF )

Are you really, really, REALLY sure the input is less than 100
characters?
{
ccarray_insert(c, line, i);
i++;

Are you sure i will never exceed 1024?

This doesn't do what you want. line is a pointer to a single
allocated area of memory. You scan the first string into that memory.
You call ccarray_insert to store the address of that memory in
c->ptr[0]. You scan the second string into the same memory, replacing
all or part of the first string, and then store the SAME ADDRESS in
c->ptr[1]. When you are all done with this loop, only the last string
is in line and all the elements of c->ptr point to this one string.
}
free(line);

Now, all the addresses in the elements of c->ptr which used to point
to line are, by definition, indeterminate. They don't point to
anything.
fclose(fptr);
}

int ccarray_print(ccarray* c)
{
int i = 0;
while ( c->ptr != NULL )


Any attempt to evaluate the address in c->ptr invokes undefined
behavior. Furthermore, at no time did you ever put a NULL value in
any c->ptr. Maybe you meant to after the loop in
ccarray_read_file.
{
printf("Line: %s\n", c->ptr );


c->ptr no longer points to a string. More undefined behavior.
i++;
}
}

int main()
{
ccarray * c = ccarray_create(c);

If you had defined ccarray_create correctly as noted above, this would
have generated a diagnostic saying you should not have an argument. As
it is, it invokes undefined behavior because the variable c has not
been assigned a value at the time the argument is evaluated before
calling the function.
ccarray_read_file(c, WORD_LIST("sample.txt"));
ccarray_print(c);
ccarray_destroy(c);
return 0;
}


Remove del for email
 
M

Mark McIntyre

On 24 Mar 2007 02:21:24 -0700, in comp.lang.c ,
After some changes, it runs fine but still it doesn't shows anything:

It doesn't even compile - please turn up your warning levels and fix
the errors you get.
ccarray* c = (ccarray*)malloc(sizeof(ccarray));

Don't cast the return from malloc. It is not required in C, and
sometimes hides a serious error (forgetting to #include stdlib.h) as
well as removing some of the compiler's ability to check your code
properly.

If you did this to get rid of a warning, you made a serious mistake.
If you did it because you usually write C++, then please remember that
C and C++ are different languages.


--
Mark McIntyre

"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,756
Messages
2,569,535
Members
45,008
Latest member
obedient dusk

Latest Threads

Top