Thread: Pointers and addresses (warning when trying to print the address)

  1. #1
    Registered User
    Join Date
    Sep 2010
    Posts
    37

    Pointers and addresses (warning when trying to print the address)

    So my problem is that I get this message when I try to print the address (in decimal) of where the pointer points to.

    "warning: format '%d' expects type 'int', but argument 2 has type 'char *' "

    If my understanding of pointers are correct, when using printf,
    ptr = prints the address of the where the pointer is pointing to
    &ptr = prints the actual address of the pointer
    *ptr = prints whatever value is held in the address


    Here's a snippet of my program:

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    void get_values(char *ptr, char *infile);
    
    int main(int argc, char *argv[]) {
       
       char text;
       char* input=NULL;
       int len=0;
       
       /*checks if user has enter correct number of command line arguements*/
       if(argc !=2) {
          printf("\nNo input file!\n");
          exit(1);
       }
    
       FILE *in = NULL;
       if ((in=fopen(argv[1], "r"))==NULL) 
          printf("\nUnable to open file\n");
       /*gets the number of characters in the file*/
       while(!feof(in)) {
          fscanf(in, "%c", &text);
          len++;
       }
       fclose(in);
    
       /*allocate memory for all characters in file*/
       input = (char *) calloc(len, sizeof(char));
    
       if (input == NULL) {
    
          printf("Unable to allocate array");
    
       }   
    
       get_values(input, argv[1]);
    
       printf("\n %d, %c", input, *input);
       printf("\n %d, %c", input+1, *(input+1));
    
       return 0;
    }
    
    
    void get_values(char *ptr, char *infile) {
    
       FILE *in = NULL;
       if ((in=fopen(infile, "r"))==NULL) 
          printf("\nUnable to open file\n");
    
    
       do{
    
          fscanf(in, "%c", ptr);
          ptr++;
    
       }while(!feof(in)) ;
    
       fclose(in);
    }
    Also, is it possible to do arithmetic with addresses, for example,
    Code:
    //lets say i have a character at address 18
    //but I want to start my output at every 8th byte,
    //so my output address will start at 16
    
    n=address%8; //n=18%8=2
    m=address-n;
    I've tried doing exactly that, but it won't let me do that. I get the error "error: invalid perands to binary % (have 'char *' and 'int')".
    Is there a way I can do this?

  2. #2
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    It's just a warning, but you actually want to do what you're doing. With a warning, the program will still compile. Did you try running it? To get rid of the warning, cast input as an int (or unsigned, which is better, and use format %u).

    Also, you should exit (or at least not continue normal processing) if you can't open the file.

    And you can find the filesize like this:
    Code:
    fseek(in, 0, SEEK_END); // set file position to end
    len = ftell(in); // read file position
    rewind(in);     // set file position back to beginning
                    // (if you want to)
    And to do general arithmetic (not just pointer arithmetic) with a pointer, cast it as an unsigned int first.
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

  3. #3
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Quote Originally Posted by ArcadeEdge View Post
    So my problem is that I get this message when I try to print the address (in decimal) of where the pointer points to.

    "warning: format '%d' expects type 'int', but argument 2 has type 'char *' "
    %d is for printing integers. It doesn't matter if that integer is a literal (42), a variable (len in your program) or an expression (len % 8). If you want to print an address, you need to use the %p modifier.

    If my understanding of pointers are correct, when using printf,
    ptr = prints the address of the where the pointer is pointing to
    &ptr = prints the actual address of the pointer
    *ptr = prints whatever value is held in the address
    Your understanding of pointer variables and the & and * operators are correct, but that is independent of printf, as I mentioned above. Note that for *ptr, the format specifier must match the type of *ptr, i.e. the type of the thing pointed to by ptr.

    Also, is it possible to do arithmetic with addresses, for example,
    Code:
    //lets say i have a character at address 18
    //but I want to start my output at every 8th byte,
    //so my output address will start at 16
    
    n=address%8; //n=18%8=2
    m=address-n;
    I've tried doing exactly that, but it won't let me do that. I get the error "error: invalid perands to binary % (have 'char *' and 'int')".
    Is there a way I can do this?
    The first one is invalid. You can only use % with actual int variables (and char, short, long, long long, and their unsigned versions). You can, however, do subtraction with pointers. Addition and subtraction of pointers is common when manipulating array elements through a pointer. Just remember, when subtracting n from a pointer, you are subtracting n * sizeof(thing pointed to) bytes, so you always move in "whole objects". That is, you can not increment an int or double pointer by just 1 byte, always by sizeof(int) or sizeof(double).
    Last edited by anduril462; 02-28-2012 at 06:10 PM.

  4. #4
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Quote Originally Posted by oogabooga View Post
    It's just a warning, but you actually want to do what you're doing. With a warning, the program will still compile. Did you try running it? To get rid of the warning, cast input as an int (or unsigned, which is better, and use format %u).
    ...
    And to do general arithmetic (not just pointer arithmetic) with a pointer, cast it as an unsigned int first.
    Casting to an int is generally a bad idea. There is no guarantee that the size of an int (or even an unsigned long long) is the same size as a pointer, or that it's big enough to hold a valid memory address (pointer). Thus you may suffer data loss in casting. Casting covers up any such warnings the compiler may generate regarding this. It may help to think of casting as you telling the compiler you know better than it does. Since that's rarely the case, you should avoid casting where possible and seek other methods.

    That being said, I'm not aware of a system that has such issues, and if you're on your PC, I'm pretty sure most implementations use the same size for pointers and ints, so it wont be an issue.

    @ArcadeEdge:
    I think the bigger question is:
    What do you mean by "start your output" at an address that's a multiple of 8, and why would you want to do that? Maybe you could explain in more detail. The code snippet you provided is prone to buffer underruns and other types of invalid memory accesses or undefined behavior.

  5. #5
    Registered User
    Join Date
    Sep 2010
    Posts
    37
    I haven't looked at the other replies in detail yet, but @anduril462

    Quote Originally Posted by anduril462 View Post
    @ArcadeEdge:
    I think the bigger question is:
    What do you mean by "start your output" at an address that's a multiple of 8, and why would you want to do that? Maybe you could explain in more detail. The code snippet you provided is prone to buffer underruns and other types of invalid memory accesses or undefined behavior.
    Well, it's part of an assignment where I have to print the address at every 8th byte starting from the beginning of the file. For example, if my text file contained "abcdedgh" and "a" is at address 10 but i want to find where "e" is (which will be at address 14) and print it out my output will be(the periods are just for spacing...):

    10 11 12 13 14 15 16 17
    a...b...c..d...e...f...g...h
    .................^

    But if "a" started at 14 and I wanted to find "c'

    10 11 12 13 14 15 16 17
    .................a...b...c..d
    ..........................^

  6. #6
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    The way I understand it, you want something similar to what you see in many hex editors/hex dumps. Perhaps like this:
    Code:
    $ hexdump -C foo.txt
    00000000  54 68 69 73 20 69 73 20  61 20 74 65 73 74 20 66  |This is a test f|
    00000010  69 6c 65 2e 0a                                    |ile..|
    00000015
    If so, then you just need to count each char and print if the counter is a multiple of 8.
    Code:
    counter = 0
    while (c = read char from file)
        if (counter % 8 == 0)
            print address (this may just be counter printed in a hex format)
        counter++

  7. #7
    Registered User
    Join Date
    Sep 2010
    Posts
    37
    Thank you anduril, I will try that but is there any way I can print the address in decimal or do I have to use %p?

  8. #8
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    If you are printing the value of a pointer, you have to use %p. But now that I understand your program a bit better, I don't think you want to print an address (in the pointer/memory address sense) at all. I think you want to print the "address" or "offset" of bytes within the file. That is, if your file contains "abcdefghijklmnop", you want something like:
    Code:
    0: a b c d e f g h
    8: i j k l m n o p
    If you try to do this with ptr in get_values(), you will likely get different addresses each time. malloc will not necessarily allocate memory at the same address for you, nor will the addresses be the same on different computers. That is why I suggested counting the bytes you read (implying that count is an int, since you only read whole bytes), and printing that. You can print that in decimal, or any other way you can print an integer in C.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Addresses and extracting the value stored at an address
    By donoe_85 in forum C Programming
    Replies: 4
    Last Post: 04-08-2009, 03:38 AM
  2. Addresses and pointers help...
    By GCNDoug in forum C Programming
    Replies: 13
    Last Post: 04-07-2007, 05:37 PM
  3. variable addresses and pointers
    By tzpb8 in forum C Programming
    Replies: 47
    Last Post: 07-26-2006, 07:08 PM
  4. Pointers, addresses, and new
    By WarBaboon in forum C++ Programming
    Replies: 7
    Last Post: 06-06-2003, 10:12 PM
  5. Pointers and their Addresses
    By incognito in forum C++ Programming
    Replies: 6
    Last Post: 12-29-2001, 07:16 PM