Thread: argc and argv not initialized properly (Visual Studio)

  1. #1
    Registered User
    Join Date
    Feb 2010
    Posts
    44

    argc and argv not initialized properly (Visual Studio)

    Hi,

    I'm writing some code that can read some data from a bitmap file. The code works fine, but when I debug the code in Visual Studio (2010) it seems that argc and argv are not initialized properly (and actually the variable 'filename' isn't read properly either) if I read from the file more than once with my function getImageInfo (I don't pass any arguments to the program yet so argc should simply be initialized to 1). Now argc is set to 32 every time.

    main program:

    Code:
    #include<stdio.h>
    #include<stdlib.h>
    #include<math.h>
    #include<alloca.h>
    #include"functions.h"
    #include<string.h>
    
    int main(int argc, char* argv[]) {
    
     FILE        *bmpInput;
     char		 filename[20];  
     int         nRows, nCols;  
     
     printf("What is the name of the file?\n");
     gets(filename);
    
     if((bmpInput = fopen(filename, "rb")) == NULL)
                {
    	     printf("Can not read BMP file");
    	     exit(0);
                }   
     	    
     nCols = getImageInfo(bmpInput, 18, 4);
     printf("Width: \t\t%d\n", nCols); 
    
     nRows = getImageInfo(bmpInput, 22, 4);
     printf("Height: \t%d\n", nRows); 
    
     fclose (bmpInput); 
    
    return 0;
    }
    If I comment the line 'nRows=...' argc and argv are properly initialized and 'filename' is read properly according to the Debugger.

    function:

    Code:
    #include<stdio.h>
    #include<stdlib.h>
    #include<math.h>
    #include<alloca.h>
    #include<fftw3.h>
    #include"functions.h"
    #include<string.h>
    
     int getImageInfo(FILE* inputFile, long offset, int numberOfChars)
     {
    
      unsigned char   *ptrC;
      int             value=0;
      unsigned char   dummy;
      int             i;
    
      ptrC = malloc(sizeof(unsigned char));
      if (ptrC == NULL)
      {
       fprintf(stderr, "out of memory\n");
       return 0;
      }
    
      /* Read at byte offset in the file */
    
      fseek(inputFile, offset, SEEK_SET);
    
      for(i=1; i<=numberOfChars; i++)
      {
         fread(ptrC, sizeof(unsigned char), 1, inputFile);
    
         value = value + (int)((*ptrC)*(pow(256, (i-1))));
      }
    
      return(value);
    
     }
    I assume something must go wrong in the function, but I can't figure out what. The strange thing is that the code just runs fine, I just happened to notice this when I was debugging. I hope that someone can tell what I am doing wrong. Thanks in advance.

    Best regards, Michiel.

  2. #2
    Registered User
    Join Date
    Dec 2007
    Posts
    2,675
    Did you set the command line arguments in the Project settings? I don't have Visual Studio, but under the Project Settings I believe there's a tab Debugging or Debugger, and under that there is something like a Command Line Arguments setting. That's where you put the values that end up in argv.

    Don't use gets() ever. FAQ > Why gets() is bad / Buffer Overflows - Cprogramming.com

    Any particular reason you're using malloc (and generating a memory leak because you're not freeing your memory) in your function? There's no reason you can't just use an automatic stack variable there.

  3. #3
    Registered User
    Join Date
    Feb 2010
    Posts
    44
    Hi rags_to_riches,

    thanks for your reply.
    I read before that there is something like 'Command arguments' in the Project Properties, but my program doesn't need any arguments yet. The strange thing is that the argc and argv are initialized correctly when the Debugger starts at the line 'int main...' if getIamgeInfo is only called once in the main program and they are not initialized correctly if getImageInfo is called more than once. After this line argc and argv are set correctly in both cases according to the Debugger. However, if getImageInfo is called more than once 'filename' starts with some random characters before the correct filename. The program still runs fine though.
    I changed gets to gets_s, because if I use fgets(filename, sizeof(filename),stdin) the pointer bmpInput becomes NULL and the program terminated prematurely. I don't know why.
    You're right that I didn't free the memory allocated with malloc() in my function so I changed it to:

    Code:
     int getImageInfo(FILE* inputFile, long offset, int numberOfChars)
     {
    
      unsigned char   *ptrC;
      int             value=0;
      unsigned char   dummy;
      int             i;
    
      dummy='0';
      ptrC=&dummy;
    
      /* Read at byte offset in the file */
    
      fseek(inputFile, offset, SEEK_SET);
    
      for(i=1; i<=numberOfChars; i++)
      {
         fread(ptrC, sizeof(unsigned char), 1, inputFile);
    
         value = value + (int)((*ptrC)*(pow(256, (i-1))));
      }
    
      return(value);
    
     }
    That should work I think.
    However, I still don't understand how come the values of argc, argv and filename change when I uncomment the second call to getImageInfo, which is actually a line after the lines when the other variables are initialized.

  4. #4
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    You aren't doing anything with argc and argv. So why do you think they "aren't initialized correctly"? If you aren't using them, just use int main( void ).


    Quzah.
    Hope is the first step on the road to disappointment.

  5. #5
    Registered User
    Join Date
    Feb 2010
    Posts
    44
    Hi Quzah,

    they are in there for future purposes. According to the description of these arguments argc should just return 1 and argv should contain the name of the program if you don't enter any arguments. This means that they should be initialized and not some random value. A line further down the main program shouldn't change that I would think.

  6. #6
    Registered User
    Join Date
    May 2010
    Posts
    4,632
    However, I still don't understand how come the values of argc, argv and filename change when I uncomment the second call to getImageInfo, which is actually a line after the lines when the other variables are initialized.
    The only reason these variables will change is because you are somehow overwriting these variables.

    Jim

  7. #7
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Tell you what: instead of just using your debugger, print argc and argv[0] at the start of the main function. What output do you see?
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  8. #8
    Registered User
    Join Date
    Mar 2011
    Posts
    546
    does your include file have the right prototype for getImageInfo?

  9. #9
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    never mind

  10. #10
    Registered User
    Join Date
    Feb 2010
    Posts
    44
    @laserlight: If I print the values they are correct. The filename is correct if I print it to the console, even though the variable in the Debugger starts with 1'r' (or something), then 6 zeros and then the real filename (only if I call getImageInfo more than once). I guess this must be an error in the Debugger then.
    @dmh2000: Yep, the include file says: int getImageInfo(FILE*, long, int);

  11. #11
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Quote Originally Posted by mvanrijnbach View Post
    According to the description of these arguments argc should just return 1 and argv should contain the name of the program if you don't enter any arguments. This means that they should be initialized and not some random value. A line further down the main program shouldn't change that I would think.
    They might contain the name of the program. It doesn't have to. It's not required by the standard. Also, how do you know they are changing? Nothing you've provided her as code shows you doing anything with them. Your code does not do anything with those variables.

    If you want to show us the code that you're actually using, then we can see what you're doing wrong. But with the code you posted, you don't do anything with argc or argv, so it doesn't matter what value your debugger says they have, because your actual code doesn't do anything with them.


    Quzah.
    Hope is the first step on the road to disappointment.

  12. #12
    Registered User
    Join Date
    Feb 2010
    Posts
    44
    @quzah:
    ok, I'm just following what I find on the internet about argc and argv:
    - argc is greater than zero.
    - argv[argc] is a null pointer.
    - argv[0] through to argv[argc-1] are pointers to strings whose meaning will be determined by the program.
    - argv[0] will be a string containing the program's name or a null string if that is not available. Remaining elements of argv represent the arguments supplied to the program. In cases where there is only support for single-case characters, the contents of these strings will be supplied to the program in lower-case.

    Actually, you're right that argc just has to be greater than zero (according to what I read about it, this might be wrong). However, I think it is strange that the value depends on a line in main being commented or not. But according to what I found on the internet argv[0] should contain the name of the program, but the variable in the Debugger didn't.
    The code I showed above is all of the code though.

  13. #13
    Registered User
    Join Date
    May 2009
    Posts
    4,183
    Unix descended OS will normally have the command name in argv[0].
    Windows based OS used to NOT have the command name in argv[0].
    Been about 15 years since I checked Windows and argv[0] value.

    Tim S.

  14. #14
    Registered User
    Join Date
    Sep 2008
    Location
    Toronto, Canada
    Posts
    1,834
    If the values displayed for argv[0] change depending on whether you comment out an irrelevant line, then your debugger is suspect. I've stopped using debuggers years ago because of just such strangeness. It's one more complexity I can do without. Just put in temporary printfs in your code to check values as others have suggested.

  15. #15
    Registered User
    Join Date
    Dec 2007
    Posts
    2,675
    Based on the things written, like this:
    I changed gets to gets_s, because if I use fgets(filename, sizeof(filename),stdin) the pointer bmpInput becomes NULL and the program terminated prematurely. I don't know why.
    i.e., stack variables getting trashed, doesn't this point to stack corruption? I'm betting this isn't the entirety of the code.

    What are you entering for a filename, by the way?

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. argv and argc
    By antros48 in forum C Programming
    Replies: 19
    Last Post: 09-30-2011, 08:26 AM
  2. how to use argc and argv
    By Salahuddin in forum C Programming
    Replies: 19
    Last Post: 09-09-2011, 03:53 AM
  3. argc, argv
    By Martas in forum C Programming
    Replies: 6
    Last Post: 11-19-2009, 09:39 AM
  4. Replies: 14
    Last Post: 12-26-2004, 11:18 AM
  5. argc--; argv++;
    By C of Green in forum C++ Programming
    Replies: 5
    Last Post: 08-13-2003, 06:16 PM