By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
448,495 Members | 1,321 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 448,495 IT Pros & Developers. It's quick & easy.

Strange command line args problem

P: n/a
Hi. I have a strange problem involving the passing of command line
arguments to a C program I'm writing. I tried posting this in
comp.programming yesterday but someone kindly suggested that I'd have
better luck here. So here goes!

My program ignores any command line arguments, or at least it's
supposed to. However, when I pass any command line arguments to the
program, the behaviour of one of the functions changes mysteriously. I
have no global variables in my program and I'm using int main(void)
rather than a version involving argc and argv parameters. So, there
shouldn't be any accidental use of those variables. There are also no
declarations of the type
extern (type) varname;
in the offending function. I'm compiling this using what I believe is
the latest version of the mingw32 gcc port under win2k. All possible
compiler optimizations are enabled. I don't think it should change
anything, but I'm working through the latest version of Bloodsheds
Dev-C++ IDE.

Here is the smallest program I could make that illustrates my problem.
It's still quite long -- sorry about that! Explanation will follow.

#include "stdlib.h"
#include "stdio.h"

char** ReadFilenamesArray(char** filenamesarray, int *numfiles, FILE
*fptr)
{
char c = EOF;
int nfiles = 0;
int flag = 0;
int index = 0;
int len = 1;

c = fgetc(fptr);
while(c != EOF) {
while(c == 32 || c == 10 || c == 13 || c == 9 || c ==
11)//whitespace
c = fgetc(fptr);
if(c == EOF)
continue;
filenamesarray = (char**)realloc(filenamesarray,
(++nfiles)*sizeof(char*));
if(filenamesarray == NULL) {
flag = 1;
break;
}
while(c != 32 && c != 10 && c != 13 && c != 9 && c != 11) {
//not whitespace
if(c == EOF)
break;
filenamesarray[index] =
(char*)realloc(filenamesarray[index], (++len) * sizeof(char));
if(filenamesarray[index] == NULL) {
flag = 1;
break;
}
filenamesarray[index][len-2] = c;
c = fgetc(fptr);
}
if(flag)
break;
filenamesarray[index][len-1] = 0; //add the null terminator
len = 1; //reset len, for next word
index++;
}
if(flag) { // flag has been set, haven't been able to allocate
memory
nfiles--;
while(nfiles >= 0) {
free(filenamesarray[nfiles]);
nfiles--;
}
free(filenamesarray);
fclose(fptr);
nfiles = 0;
}
fclose(fptr);
*numfiles = nfiles;
if(flag)
return NULL;
else
return filenamesarray;
}

int main(void)
{
char **reminderfiles = NULL;
FILE *fptr = NULL;
int numfiles = 0;
int i = 0;

if( (fptr = fopen("reminders.in", "r")) == NULL) {
printf("Cannot locate reminders.in\n");
exit(0);
}
//Read list of filenames into reminderfiles array
reminderfiles = ReadFilenamesArray(reminderfiles, &numfiles,
fptr);
if( reminderfiles == NULL) {
printf("not enough memory\n");
fclose(fptr);
exit(0);
}
fclose(fptr);
for(i = 0; i < numfiles; i++) {
printf("File %d is %s\n", i, reminderfiles[i]);
free(reminderfiles[i]);
}
free(reminderfiles);
system("pause\n");

return 0;
}
This program is supposed to open a file called reminders.in in the
same directory as the executable and read white-space seperated words
into an 'array of strings'. This is essentially done with the
ReadFilenamesArray() function. My version of reminders.in has only the
following three lines:
tmpthing.wtf
somefile.txt
other.old

The output of the program without any command line arguments passed is
as follows:
File 0 is tmpthing.wtf
File 1 is somefile.txt
File 2 is other.old

Here is the output when any arbitrary argument is passed to the
executable:
File 0 is somefile.txt
File 1 is tmptfile.txt
File 2 is other.old

As you can see things get a bit jumbled. I really have no idea why. I
hope it's something really daft I'm doing, but I can't see it for the
life of me. Why would passing an arbitrary argument affect the
behaviour of a function unrelated to any command line args in such a
way? Can anyone help!? Once again, apologies for the length of the
post, I didn't see how I could cut it down much further.

Edd
Nov 13 '05 #1
Share this Question
Share on Google+
6 Replies


P: n/a
Edd Dawson wrote:
Hi. I have a strange problem involving the passing of command line
arguments to a C program I'm writing. I tried posting this in
comp.programming yesterday but someone kindly suggested that I'd have
better luck here. So here goes!

My program ignores any command line arguments, or at least it's
supposed to. However, when I pass any command line arguments to the
program, the behaviour of one of the functions changes mysteriously. I
have no global variables in my program and I'm using int main(void)
rather than a version involving argc and argv parameters. So, there
shouldn't be any accidental use of those variables. There are also no
declarations of the type
extern (type) varname;
in the offending function. I'm compiling this using what I believe is
the latest version of the mingw32 gcc port under win2k. All possible
compiler optimizations are enabled. I don't think it should change
anything, but I'm working through the latest version of Bloodsheds
Dev-C++ IDE.

Here is the smallest program I could make that illustrates my problem.
It's still quite long -- sorry about that! Explanation will follow.

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

char** ReadFilenamesArray(char** filenamesarray, int *numfiles, FILE
*fptr)
{
char c = EOF;
Erm, no. You want

int c = EOF;

(fgetc() returns an *int*, specifically to allow for EOF, which need
not be representable as a char)
int nfiles = 0;
int flag = 0;
int index = 0;
int len = 1;

c = fgetc(fptr);
while(c != EOF) {
while(c == 32 || c == 10 || c == 13 || c == 9 || c ==
11)//whitespace
Include <ctype.h> and use isspace(). Magic numbers are ugly.
c = fgetc(fptr);
if(c == EOF)
continue;
filenamesarray = (char**)realloc(filenamesarray,
(++nfiles)*sizeof(char*));
Don't cast the return value of *alloc(). It's unnecessary and can
hide errors.

When using realloc(), always receive the return value in a temporary
variable; otherwise, if it fails you have a memory leak.
if(filenamesarray == NULL) {
flag = 1;
break;
}
while(c != 32 && c != 10 && c != 13 && c != 9 && c != 11) {
//not whitespace
See above.
if(c == EOF)
break;
filenamesarray[index] =
(char*)realloc(filenamesarray[index], (++len) * sizeof(char));
See above regarding the cast.
`sizeof(char)' is 1 by definition so why bother?
if(filenamesarray[index] == NULL) {
flag = 1;
break;
}
filenamesarray[index][len-2] = c;
c = fgetc(fptr);
}
if(flag)
break;
filenamesarray[index][len-1] = 0; //add the null terminator
len = 1; //reset len, for next word
index++;
}
if(flag) { // flag has been set, haven't been able to allocate
memory
nfiles--;
while(nfiles >= 0) {
free(filenamesarray[nfiles]);
No, you've already lost the value of that pointer.
nfiles--;
}
free(filenamesarray);
fclose(fptr);
nfiles = 0;
}
fclose(fptr);
*numfiles = nfiles;
if(flag)
return NULL;
else
return filenamesarray;
}

int main(void)
{
char **reminderfiles = NULL;
FILE *fptr = NULL;
int numfiles = 0;
int i = 0;

if( (fptr = fopen("reminders.in", "r")) == NULL) {
printf("Cannot locate reminders.in\n");
exit(0);
exit(0) typically indicates `success'. This does not look like
`success'.
}
//Read list of filenames into reminderfiles array
reminderfiles = ReadFilenamesArray(reminderfiles, &numfiles,
fptr);
if( reminderfiles == NULL) {
printf("not enough memory\n");
fclose(fptr);
exit(0);
}
fclose(fptr);
for(i = 0; i < numfiles; i++) {
printf("File %d is %s\n", i, reminderfiles[i]);
free(reminderfiles[i]);
}
free(reminderfiles);
system("pause\n");

return 0;
}
This program is supposed to open a file called reminders.in in the
same directory as the executable and read white-space seperated words
into an 'array of strings'. This is essentially done with the
ReadFilenamesArray() function. My version of reminders.in has only the
following three lines:
tmpthing.wtf
somefile.txt
other.old

The output of the program without any command line arguments passed is
as follows:
File 0 is tmpthing.wtf
File 1 is somefile.txt
File 2 is other.old

Here is the output when any arbitrary argument is passed to the
executable:
File 0 is somefile.txt
File 1 is tmptfile.txt
File 2 is other.old

As you can see things get a bit jumbled. I really have no idea why. I
hope it's something really daft I'm doing, but I can't see it for the
life of me. Why would passing an arbitrary argument affect the
behaviour of a function unrelated to any command line args in such a
way? Can anyone help!? Once again, apologies for the length of the
post, I didn't see how I could cut it down much further.

Your 'ReadFilenamesArray()' function is *way* too complicated for what
it does; as a result, I suspect you're looking at memory you don't
legitimately
have access to.

A suggestion:

Allocating extra space, char by char, is a Bad Idea. Why not
allocate a `large enough' buffer to read into -- and only realloc()
(by a reasonable amount -- 1 is not a reasonable amount) if you
guessed wrong?

In general, whenever possible -- SIMPLIFY!

I suspect that as part of the process of cleaning up your code,
you'll find the error.

HTH,
--ag
--
Artie Gold -- Austin, Texas

Nov 13 '05 #2

P: n/a
ho******@planetquake.com (Edd Dawson) wrote:
Hi. I have a strange problem involving the passing of command line
arguments to a C program I'm writing. I tried posting this in
comp.programming yesterday but someone kindly suggested that I'd have
better luck here. So here goes!

My program ignores any command line arguments, or at least it's
supposed to. However, when I pass any command line arguments to the
program, the behaviour of one of the functions changes mysteriously. I
have no global variables in my program and I'm using int main(void)
rather than a version involving argc and argv parameters. So, there
shouldn't be any accidental use of those variables. There are also no
declarations of the type
extern (type) varname;
in the offending function. I'm compiling this using what I believe is
the latest version of the mingw32 gcc port under win2k. All possible
compiler optimizations are enabled. I don't think it should change
anything, but I'm working through the latest version of Bloodsheds
Dev-C++ IDE.

Here is the smallest program I could make that illustrates my problem.
It's still quite long -- sorry about that! Explanation will follow.

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

char** ReadFilenamesArray(char** filenamesarray, int *numfiles, FILE
*fptr)
{
char c = EOF; int c = ...
int nfiles = 0;
int flag = 0;
int index = 0;
int len = 1;

c = fgetc(fptr);
while(c != EOF) {
while(c == 32 || c == 10 || c == 13 || c == 9 || c ==
11)//whitespace
Why not:

while ( isspace( c ) )

(You have to #include <ctype.h> in order to use it.)

c = fgetc(fptr);
if(c == EOF)
continue;
filenamesarray = (char**)realloc(filenamesarray, Unnecessary cast to malloc()s return value.
(++nfiles)*sizeof(char*)); ^^^^^^^^^^^^^ this is 1 per definitionem
if(filenamesarray == NULL) {
flag = 1;
break;
} Insert the following line here (explanation below):

filenamesarray[index] = NULL;
while(c != 32 && c != 10 && c != 13 && c != 9 && c != 11) {
//not whitespace
see above.
if(c == EOF)
break;
filenamesarray[index] =
(char*)realloc(filenamesarray[index], (++len) * sizeof(char));

Uh-oh, filenamesarray[index] has not been initialized to NULL, so you
invoke undefined behaviour here. This will likely garble up your
memory, and that is probably the reason for the "strange" behaviour of
your program. You were just (un)lucky that nothing more serious
happened. I just added some more lines to reminder.in and the program
produced a nice segfault!

[OT]
BTW: I use the same environment as you: latest DevC++/MingW32 under W2K,
and, surprisingly or not, was able to exactely reproduce the effects you
described.

I suggest the use of the debugger that comes with DevC++/MingW32 to
track down errors like this - it's worth it. :)
[/OT]

<SNIP>

Warning: I did not perform an in-deep analysis of your code, so it might
turn out that it contains more flaws than the mentioned one ...

Hope this helped.

Regards

Irrwahn
--
do not write: void main(...)
do not use gets()
do not cast the return value of malloc()
do not fflush( stdin )
read the c.l.c-faq: http://www.eskimo.com/~scs/C-faq/top.html
Nov 13 '05 #3

P: n/a
Edd Dawson <ho******@planetquake.com> wrote:
Hi. I have a strange problem involving the passing of command line
arguments to a C program I'm writing. I tried posting this in
comp.programming yesterday but someone kindly suggested that I'd have
better luck here. So here goes!

My program ignores any command line arguments, or at least it's
supposed to. However, when I pass any command line arguments to the
program, the behaviour of one of the functions changes mysteriously. I
have no global variables in my program and I'm using int main(void)
rather than a version involving argc and argv parameters. So, there
shouldn't be any accidental use of those variables. There are also no
declarations of the type
extern (type) varname;
in the offending function. I'm compiling this using what I believe is
the latest version of the mingw32 gcc port under win2k. All possible
compiler optimizations are enabled. I don't think it should change
anything, but I'm working through the latest version of Bloodsheds
Dev-C++ IDE.

Here is the smallest program I could make that illustrates my problem.
It's still quite long -- sorry about that! Explanation will follow.

#include "stdlib.h"
#include "stdio.h"

char** ReadFilenamesArray(char** filenamesarray, int *numfiles, FILE
*fptr)
{
char c = EOF;
int nfiles = 0;
int flag = 0;
int index = 0;
int len = 1;

c = fgetc(fptr);
while(c != EOF) {
c should be an int, not a char - fgetc returns either a number in the
range of unsigned char, or EOF (which must be negative). So stuffing
the result into a char might mean that the comparison with EOF is never
true - or it might mean that it's true even when EOF Isn't reached.
while(c == 32 || c == 10 || c == 13 || c == 9 || c ==
11)//whitespace
The ASCII character set is not universal, and C doesn't mandate it.
Those should be:

while (c == ' ' || c == '\n' || c == '\t' || c =='\f')

(You only need to check for '\n' because when you open a stream in text
mode in C, the platform's local line-ending convention is converted to a
single '\n' from the point of view of the C program). An even better
alternative is:

#include <ctype.h>

while (c != EOF && isspace(c))
c = fgetc(fptr);
if(c == EOF)
continue;
filenamesarray = (char**)realloc(filenamesarray,
(++nfiles)*sizeof(char*));
There's no need to cast the return value of realloc - it's void * which
is implicitly convertable to any other object pointer type.

However, you do need to store the return value of malloc in a different
variable, until you check if it's NULL - consider what happens when
realloc returns NULL. You set flag to 1, break out of the loop - then
try to dereference filenamesarray, which is now NULL!
if(filenamesarray == NULL) {
flag = 1;
break;
}
while(c != 32 && c != 10 && c != 13 && c != 9 && c != 11) {
//not whitespace
while (c != EOF && !isspace(c))
if(c == EOF)
break;
filenamesarray[index] =
(char*)realloc(filenamesarray[index], (++len) * sizeof(char));
You assume here that filenamesarray[index] starts off at NULL - but it
doesn't, since it is itself fresh memory from realloc to begin with, so
it's effectively an uninitialised variable. You need to put a:

filenamesarray[index] = NULL;

before this while loop.

Again, you can drop the cast on realloc and you need to save the return
value in a temporary before overwriting the old value of
filenamesarray[index].
if(filenamesarray[index] == NULL) {
flag = 1;
break;
}
filenamesarray[index][len-2] = c;
c = fgetc(fptr);
}
if(flag)
break;
I don't believe this branch of the if can ever be taken?
filenamesarray[index][len-1] = 0; //add the null terminator
len = 1; //reset len, for next word
index++;
}
if(flag) { // flag has been set, haven't been able to allocate
memory
nfiles--;
while(nfiles >= 0) {
free(filenamesarray[nfiles]);
nfiles--;
}
free(filenamesarray);
fclose(fptr);
nfiles = 0;
}
fclose(fptr);
*numfiles = nfiles;
if(flag)
return NULL;
else
return filenamesarray;
}


The rest seems OK at a glance. Have you tried running it through
valgrind?

- Kevin.

Nov 13 '05 #4

P: n/a
Edd Dawson wrote:

Hi. I have a strange problem involving the passing of command line
arguments to a C program I'm writing. I tried posting this in
comp.programming yesterday but someone kindly suggested that I'd have
better luck here. So here goes!
You failed to follow my advice about avoiding // comments and
limiting line length, and you started a new thread.

.... snip ... anything, but I'm working through the latest version of Bloodsheds
Dev-C++ IDE.

Here is the smallest program I could make that illustrates my problem.
It's still quite long -- sorry about that! Explanation will follow.

#include "stdlib.h"
#include "stdio.h"

char** ReadFilenamesArray(char** filenamesarray, int *numfiles,
FILE *fptr)

illustrating keeping line lengths down. Now, are you sure you
want this function to return a pointer to a pointer to a char
array?
{
char c = EOF;
This is certainly wrong. A char cannot hold EOF. you want int
here
int nfiles = 0;
int flag = 0;
int index = 0;
int len = 1;

c = fgetc(fptr);
while(c != EOF) {
This will not be reliable, because of the declaration of c
while(c == 32 || c == 10 || c == 13 || c == 9 || c ==
11)//whitespace
This involves magic numbers, and may or may not be correct on
your system. Try "isspace((unsigned char)c)" and/or
"isprint((unsigned char)c)". The unsigned char is important. At
the very least use ' ', '\n', '\r', '\t', etc.
c = fgetc(fptr);
if(c == EOF)
continue;
Won't be found.
filenamesarray = (char**)realloc(filenamesarray,
(++nfiles)*sizeof(char*));
Eliminate the cast. I suspect the logic is flawed. In main you
appear to be using an array of pointers to lines, so you need to
allocate space for that line, and place that pointer into the
(possibly expanded) array of char pointers.
if(filenamesarray == NULL) {
flag = 1;
break;
}
while(c != 32 && c != 10 && c != 13 && c != 9 && c != 11) {
//not whitespace
if(c == EOF)
break;
filenamesarray[index] =
(char*)realloc(filenamesarray[index], (++len) * sizeof(char));
if(filenamesarray[index] == NULL) {
flag = 1;
break;
}
filenamesarray[index][len-2] = c;
c = fgetc(fptr);
}
if(flag)
break;
filenamesarray[index][len-1] = 0; //add the null terminator
len = 1; //reset len, for next word
index++;
}
if(flag) { // flag has been set, haven't been able to allocate
memory
nfiles--;
while(nfiles >= 0) {
free(filenamesarray[nfiles]);
nfiles--;
}
free(filenamesarray);
fclose(fptr);
nfiles = 0;
}
fclose(fptr);
*numfiles = nfiles;
if(flag)
return NULL;
else
return filenamesarray;
}

int main(void)
{
char **reminderfiles = NULL;
FILE *fptr = NULL;
int numfiles = 0;
int i = 0;

if( (fptr = fopen("reminders.in", "r")) == NULL) {
printf("Cannot locate reminders.in\n");
exit(0);
}
//Read list of filenames into reminderfiles array
reminderfiles = ReadFilenamesArray(reminderfiles, &numfiles,
fptr);
if( reminderfiles == NULL) {
printf("not enough memory\n");
fclose(fptr);
exit(0);
}
fclose(fptr);
for(i = 0; i < numfiles; i++) {
printf("File %d is %s\n", i, reminderfiles[i]);
free(reminderfiles[i]);
}
free(reminderfiles);
system("pause\n");

return 0;
}

This program is supposed to open a file called reminders.in in the
same directory as the executable and read white-space seperated words
into an 'array of strings'. This is essentially done with the
ReadFilenamesArray() function. My version of reminders.in has only the
following three lines:
tmpthing.wtf
somefile.txt
other.old

The output of the program without any command line arguments passed is
as follows:
File 0 is tmpthing.wtf
File 1 is somefile.txt
File 2 is other.old

Here is the output when any arbitrary argument is passed to the
executable:
File 0 is somefile.txt
File 1 is tmptfile.txt
File 2 is other.old

As you can see things get a bit jumbled. I really have no idea why. I
hope it's something really daft I'm doing, but I can't see it for the
life of me. Why would passing an arbitrary argument affect the
behaviour of a function unrelated to any command line args in such a
way? Can anyone help!? Once again, apologies for the length of the
post, I didn't see how I could cut it down much further.


The above interspersed comments may begin to help.

--
Replies should be to the newsgroup
Chuck Falconer, on vacation.
Nov 13 '05 #5

P: n/a
LibraryUser <de**********@made.invalid> wrote in message news:<3F***************@made.invalid>...
Edd Dawson wrote:

Hi. I have a strange problem involving the passing of command line
arguments to a C program I'm writing. I tried posting this in
comp.programming yesterday but someone kindly suggested that I'd have
better luck here. So here goes!
You failed to follow my advice about avoiding // comments and
limiting line length, and you started a new thread.


Yes, apologies for that. I didn't see that post before I made this
one.
... snip ...
anything, but I'm working through the latest version of Bloodsheds
Dev-C++ IDE.

Here is the smallest program I could make that illustrates my problem.
It's still quite long -- sorry about that! Explanation will follow.

#include "stdlib.h"
#include "stdio.h"
Sorry, should have use <> rather than "" as someone pointed out. Made
this a bit quickly. Compiler didn't complain and program ran so I
didn't notice.
char** ReadFilenamesArray(char** filenamesarray,

int *numfiles,
FILE *fptr)

illustrating keeping line lengths down. Now, are you sure you
want this function to return a pointer to a pointer to a char
array?


I'm sure I want it to return a pointer to a pointer to a char, not a
pointer to a pointer to a char array. I think this is correct for the
former case?
{
char c = EOF;


This is certainly wrong. A char cannot hold EOF. you want int
here


Ok. I didn't know that. I have used this in a couple of other programs
with success so I've never come across the problem. I'll change it
though. Thanks.
int nfiles = 0;
int flag = 0;
int index = 0;
int len = 1;

c = fgetc(fptr);
while(c != EOF) {


This will not be reliable, because of the declaration of c
while(c == 32 || c == 10 || c == 13 || c == 9 || c ==
11)//whitespace


This involves magic numbers, and may or may not be correct on
your system. Try "isspace((unsigned char)c)" and/or
"isprint((unsigned char)c)". The unsigned char is important. At
the very least use ' ', '\n', '\r', '\t', etc.


I didn't know those functions existed. Prior to this post I had my own
WhiteSpace() functio, but that added an extra few lines, so I replaced
the call with those character checks. It will be changed :)
c = fgetc(fptr);
if(c == EOF)
continue;


Won't be found.


It will on my system (perhaps in a minority group of systems!). But
again, I'll change it.
filenamesarray = (char**)realloc(filenamesarray,
(++nfiles)*sizeof(char*));


Eliminate the cast. I suspect the logic is flawed. In main you
appear to be using an array of pointers to lines, so you need to
allocate space for that line, and place that pointer into the
(possibly expanded) array of char pointers.


Ok. The point of this function was that I didn't know how many lines
there would be, nor how long each line would be, so I'd allocate the
space as I went along. The end result should be the same, no? Well it
isn't when i pass arguments, which is the meat and potatoes of my
problem.
if(filenamesarray == NULL) {
flag = 1;
break;
}
while(c != 32 && c != 10 && c != 13 && c != 9 && c != 11) {
//not whitespace
if(c == EOF)
break;
filenamesarray[index] =
(char*)realloc(filenamesarray[index], (++len) * sizeof(char));
if(filenamesarray[index] == NULL) {
flag = 1;
break;
}
filenamesarray[index][len-2] = c;
c = fgetc(fptr);
}
if(flag)
break;
filenamesarray[index][len-1] = 0; //add the null terminator
len = 1; //reset len, for next word
index++;
}
if(flag) { // flag has been set, haven't been able to allocate
memory
nfiles--;
while(nfiles >= 0) {
free(filenamesarray[nfiles]);
nfiles--;
}
free(filenamesarray);
fclose(fptr);
nfiles = 0;
}
fclose(fptr);
*numfiles = nfiles;
if(flag)
return NULL;
else
return filenamesarray;
}

int main(void)
{
char **reminderfiles = NULL;
FILE *fptr = NULL;
int numfiles = 0;
int i = 0;

if( (fptr = fopen("reminders.in", "r")) == NULL) {
printf("Cannot locate reminders.in\n");
exit(0);
}
//Read list of filenames into reminderfiles array
reminderfiles = ReadFilenamesArray(reminderfiles, &numfiles,
fptr);
if( reminderfiles == NULL) {
printf("not enough memory\n");
fclose(fptr);
exit(0);
}
fclose(fptr);
for(i = 0; i < numfiles; i++) {
printf("File %d is %s\n", i, reminderfiles[i]);
free(reminderfiles[i]);
}
free(reminderfiles);
system("pause\n");

return 0;
}

This program is supposed to open a file called reminders.in in the
same directory as the executable and read white-space seperated words
into an 'array of strings'. This is essentially done with the
ReadFilenamesArray() function. My version of reminders.in has only the
following three lines:
tmpthing.wtf
somefile.txt
other.old

The output of the program without any command line arguments passed is
as follows:
File 0 is tmpthing.wtf
File 1 is somefile.txt
File 2 is other.old

Here is the output when any arbitrary argument is passed to the
executable:
File 0 is somefile.txt
File 1 is tmptfile.txt
File 2 is other.old

As you can see things get a bit jumbled. I really have no idea why. I
hope it's something really daft I'm doing, but I can't see it for the
life of me. Why would passing an arbitrary argument affect the
behaviour of a function unrelated to any command line args in such a
way? Can anyone help!? Once again, apologies for the length of the
post, I didn't see how I could cut it down much further.


The above interspersed comments may begin to help.

Nov 13 '05 #6

P: n/a
> Uh-oh, filenamesarray[index] has not been initialized to NULL, so you
invoke undefined behaviour here. This will likely garble up your
memory, and that is probably the reason for the "strange" behaviour of
your program. You were just (un)lucky that nothing more serious
happened. I just added some more lines to reminder.in and the program
produced a nice segfault!
Just adding that line seems to have corrected the problem. I'll sift
through the function a bit better to check for further errers.
[OT]
BTW: I use the same environment as you: latest DevC++/MingW32 under W2K,
and, surprisingly or not, was able to exactely reproduce the effects you
described.

I suggest the use of the debugger that comes with DevC++/MingW32 to
track down errors like this - it's worth it. :)
[/OT]

<SNIP>

Warning: I did not perform an in-deep analysis of your code, so it might
turn out that it contains more flaws than the mentioned one ...
Indeed!
Hope this helped.


Certainly did. Thanks!

Edd
Nov 13 '05 #7

This discussion thread is closed

Replies have been disabled for this discussion.