Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Strange Error after printing argv values

Reply
Thread Tools

Strange Error after printing argv values

 
 
Martin Ambuhl
Guest
Posts: n/a
 
      07-23-2007
Matt wrote:
> The relevant part of my code reads as follows:
>
> for ( i = 0 ; i < argc ; i++ )
>
> {
>
> printf("\narg = %d\n" , argc );
>
> printf("\nCommand line arguement %d: %s. \n", i , *argv[i] );
>
> and the stdio.h header is loaded at the start. You may notice I have
> added a * before the argv[i] as I realised I wished to print the value
> the pointer points at, was this a correct thing to do?


Almost certainly not. Check the following code. It may contain clues
to the solution to your problem. Or not. It's hard to tell from your
statement what it is you really want.

#include <stdio.h>

int main(int argc, char *argv[])
{
size_t i;
printf("arg = %d\n", argc);
for (i = 0; i < (size_t) argc; i++) {
if (argv[i])
printf("Command line argument %zu @ %p = \"%s\".\n", i,
(void *) argv[i], argv[i]);
else
printf("Command line argument %zu @ %p (null pointer).\n", i,
(void *) argv[i]);
}
return 0;
}


$a foo bar lisp green
arg = 5
Command line argument 0 @ 939d0 = "./a.exe".
Command line argument 1 @ 93a00 = "foo".
Command line argument 2 @ 93a30 = "bar".
Command line argument 3 @ 93a60 = "lisp".
Command line argument 4 @ 93a90 = "green".

>
> Something else that is rather worrying is that if I comment this bit
> out, later in the programme when it tries to read argv[1], I get
> another segmentation fault. I assume this only happens when argv[1] =
> NULL, but since I am almost certain the programme to supplied with at
> least one argument, and that the error occurs when I try to print
> argv[0] (which is the one thing that cannot be NULL!), something else
> must be wrong here.


Something is wrong, but unless our crystal balls produce your code, no
one can even guess what errors you have made.

 
Reply With Quote
 
 
 
 
Ben Bacarisse
Guest
Posts: n/a
 
      07-23-2007
Matt <(E-Mail Removed)> writes:

> The programme in its entirity is far too large I'm afraid.


But you will probably solve the problems your self as you try to cut
it down to a minimal test case that fails. You will either find the
error or remain baffled with a small test program you *can* post.

> Basically
> the bit of troublesome code arises from my implementation of the
> getopt_long function from the GNU library:
>
> http://www.gnu.org/software/libc/man...t-Long-Options
>
> with the example code:
>
> http://www.gnu.org/software/libc/man...Option-Example
>
> My implemtation is as follows:
>
> for ( i = 0 ; i < argc ; i++ )
>
> {
>
> printf("\nargc = %d\n" , argc );
>
> printf("\nCommand line arguement %d: %s. \n", i , argv[i] );
>
> while (1)
>
> {
>
> static struct option long_options[] =
>
> {
>
> // These options set a flag.
> {"stack" , no_argument , &stack_mode , 1}, // Enable
> stack (convolution) mode
>
> // These options don't set a flag. We distinguish them
> by their indices.
> {"configfile" , required_argument , 0 , 'c'},
> {0 , 0 , 0 , 0}
>
> };
>
> // getopt_long stores the option index here.
> int option_index = 0;
>
> *getopt_val = getopt_long (argc, argv, "c:", long_options,
> &option_index);


This looks very suspicious but how can we tell? What is getopt_val?
It it really a pointer to int, and does it point to a modifiable int
object? At the very least we'd need the declaration and the code that
might affect it's value from declaration to this point.

Post a small test program. Making one will teach you far more than
all the replies you might get here put together.

--
Ben.
 
Reply With Quote
 
 
 
 
Matt
Guest
Posts: n/a
 
      07-23-2007
> Post a small test program. Making one will teach you far more than
> all the replies you might get here put together.


I'll give that a go.

In the meantime, DDD now reports that with my present code, the
segmentation fault occurs when I call the getopt_long function in the
above code:

"*getopt_val = getopt_long (argc, argv, "c:", long_options,
&option_index);"

Is this another example of where I shouldn't have used a *?

Kind Regards,

Matt

 
Reply With Quote
 
Matt
Guest
Posts: n/a
 
      07-23-2007
On Jul 23, 10:32 am, Matt <(E-Mail Removed)> wrote:
> > Post a small test program. Making one will teach you far more than
> > all the replies you might get here put together.

>


Having made a test programme as follows:

"// A programme to test argc and argv

// Load function libraries

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

// Main function

int main(int argc , char **argv)

{

int i; // DO loop index

// Print out argc and argv to screen

for ( i = 0 ; i < argc ; i++ )

{

printf("argc = %d\n",argc);
printf("argv[0] = %s\n",argv[0]);

}

}"

I had no errors, so calling the functions themselves doesn't seem the
be the problem.

I have since gone and commented out the getopt_long code I had added
and reintroduced the original code I had to read in the arguments:

" for ( i = 0 ; i < argc ; i++ ) // argc is the number of commmand
line arguements passed to the programme.

{

// Compare first two characters from command line arguement. If
they match, return 0 and execute statement.
if (!( strncmp( argv[i] , "-c" , 2 )))

{

sprintf( config_file , "%s" , argv[ i+1 ] ); // Point programme
to a new config file by changing the
// config_file string to the argument following "-c".

}"

Interestingly, the programme now works flawlessly as it did before,
which clearly indicates the code I posted earlier for the getopt_long
code is the cause of my errors. I will endeavour to produce another
test programme to try and replicate the segmentation fault and post
back later.

Thanks for all the excellent responses so far.

Kind Regards,

Matt


 
Reply With Quote
 
Matt
Guest
Posts: n/a
 
      07-23-2007
I have just tried running the code given from the GNU Example page,
and as I should have expected, the code was fine.

Now when I put my own implementation of this code (which is of course
very similar) by itself, I got a segmentation fault whenever I put in
an argument such as "-c" or "-stack" that the programme is meant to
recognise and act upon. The problem does not occur if I use "c" or
"stack":

// A programme to test my implementation of the getopt_long function
in an independant environment from the main programme

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

static int stack_mode = 0;

int main( int argc , char *argv[] )

{

extern int stack_mode;

char *getopt_val;
int i;

opterr = 0;

printf("argc = %d\n",argc);

for ( i = 0 ; i < argc ; i++ )

{

printf("argv[%d] = %s\n",i,argv[i]);

}

for ( i = 0 ; i < argc ; i++ ) // argc is the number of command line
arguments passed to the programme.

{

while (1)

{

static struct option long_options[] =

{

// These options set a flag.
{"stack" , no_argument , &stack_mode , 1}, // Enable stack
(convolution) mode

// These options don't set a flag. We distinguish them
by their indices.
{"configfile" , required_argument , 0 , 'c'},
{0 , 0 , 0 , 0}

};

// getopt_long stores the option index here.
int option_index = 0;

getopt_val = getopt_long (argc, argv, "c:", long_options,
&option_index);

// Detect the end of the options.
if (getopt_val == -1)

{

break;

}

switch (*getopt_val)

{

case 0:
/* If this option set a flag, do nothing else now. */
if ( long_options[option_index].flag != 0)

{

break;

}

printf ("option %s", long_options[option_index].name);

if (optarg)

{

printf (" with arg %s", optarg);

}

printf ("\n");
break;

case 'c':
printf ("option -c with value `%s'\n", optarg);
break;

case '?':
/* getopt_long already printed an error message. */
break;

default:
abort ();

}

}

/* Print any remaining command line arguments (not options). */
if (optind < argc)

{

printf ("non-option ARGV-elements: ");

while (optind < argc)

{

printf ("%s ", argv[optind++]);

}

putchar ('\n');

}

}

}

I have tried replacing "case 'c':" with "case '-c':" and so forth in
the case statements starting on line 92, but the source code would not
compile.

Kind Regards,

Matt


 
Reply With Quote
 
Matt
Guest
Posts: n/a
 
      07-23-2007
Forgot to mention, the code above should compile so feel free to give
it a try.

 
Reply With Quote
 
Ben Bacarisse
Guest
Posts: n/a
 
      07-23-2007
Matt <(E-Mail Removed)> writes:

>> Post a small test program. Making one will teach you far more than
>> all the replies you might get here put together.

>
> I'll give that a go.
>
> In the meantime, DDD now reports that with my present code, the
> segmentation fault occurs when I call the getopt_long function in the
> above code:
>
> "*getopt_val = getopt_long (argc, argv, "c:", long_options,
> &option_index);"
>
> Is this another example of where I shouldn't have used a *?


How could anyone tell? At the very least, show us the variable's
declaration and everywhere it is set.

You can't learn to program in C by added and removing * to see what
works. One you program will work and you will be happy. Lots of
programs "work" (i.e. behave as expected), with certain test cases
compiled with a particular compiler, on one particular system.

--
Ben.
 
Reply With Quote
 
Ben Bacarisse
Guest
Posts: n/a
 
      07-23-2007
Matt <(E-Mail Removed)> writes:

> I have just tried running the code given from the GNU Example page,
> and as I should have expected, the code was fine.
>
> Now when I put my own implementation of this code (which is of course
> very similar) by itself, I got a segmentation fault whenever I put in
> an argument such as "-c" or "-stack" that the programme is meant to
> recognise and act upon. The problem does not occur if I use "c" or
> "stack":


Excellent -- a program we can read from top to bottom.

> char *getopt_val;

....
> getopt_val = getopt_long (argc, argv, "c:", long_options,
> &option_index);


A problem. getopt_long (OK not topical, but the error is) returns an
it. getopt_val should be a "int" not a "char *".

> switch (*getopt_val)


Boom! getopt_val does not point to an object so * of it causes
undefined behaviour.

Look at the declarations for any functions you use, and (by and large)
you will save any results returned in variables of that type.

--
Ben.
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      07-23-2007
Matt <(E-Mail Removed)> writes:
>> Post a small test program. Making one will teach you far more than
>> all the replies you might get here put together.

>
> I'll give that a go.

[snip]

Please don't snip attribution lines. Quoting someone else's writing
without credit is considered rude.

--
Keith Thompson (The_Other_Keith) http://www.velocityreviews.com/forums/(E-Mail Removed) <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      07-23-2007
Matt <(E-Mail Removed)> writes:
[...]
> // Print out argc and argv to screen
>
> for ( i = 0 ; i < argc ; i++ )
>
> {
>
> printf("argc = %d\n",argc);
> printf("argv[0] = %s\n",argv[0]);
>
> }

[...]

The value of argc is a single number that doesn't change; why do you
print it inside the loop?

On each iteration of the loop, you print the value of argv[0]. You
almost certainly want to print argv[i].

Take a look at this. It's not intended to solve your problem, just to
demonstrate how to deal with argc and argv. Checking each argument
against NULL is perhaps overkill, but it's better to be too cautious
than not cautious enough.

#include <stdio.h>
int main(int argc, char **argv)
{
int i;
printf("argc = %d\n", argc);
for (i = 0; i < argc; i ++) {
if (argv[i] == NULL) {
printf("argv[%d] = NULL\n", i);
}
else {
printf("argv[%d] = \"%s\"\n", i, argv[i]);
}
}
return 0;
}

Also, please don't use "//" comments when posting to Usenet. They're
not supported in C90 (though many compilers support them as an
optional extension), and they can cause problems with line wrapping.
If Usenet software somewhere splits a "//" comment across two lines,
it creates a syntax error. If a "/* ... */" comment is split, it's
generally not a problem. And keep your lines short, no more than 72
columns.

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
char **argv & char *argv[] jab3 C Programming 5 12-08-2004 08:15 AM
int main(int argc, char *argv[] ) vs int main(int argc, char **argv ) Hal Styli C Programming 14 01-20-2004 10:00 PM
difference(s) between char** argv and char* argv[] David C Programming 10 09-15-2003 06:58 AM
char **argv vs. char* argv[] Bret C Programming 21 09-03-2003 03:24 AM
sys.argv[0] - 'module' object has no attribute 'argv' =?ISO-8859-1?Q?Thomas_N=FCcker?= Python 0 06-30-2003 02:07 PM



Advertisments