-2

I have to code this little task and can´t find my mistake. It should just read some data from a file and copy it in opposite order into another one. The first part seems to work, but the while-part gives me "Bad Address" for every time the write function is used. I´m grateful for every idea!

#include <iostream>
#include <cerrno>
#include <fcntl.h>
#include <cstdio>
#include <cstring>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>


#define TRY(cmd,msg) {                                          \
    if ((cmd) < 0) {                                            \
      std::cerr << (msg) << ": " << strerror(errno) << std::endl;       \
    }                                                                   \
  }


int main(int argc, char *argv[]){
    int fd_in, fd_out, rest;
    off_t map_size, offset, length;
    char * addr;    
    struct stat sb;

    if (argc != 3) {
        std::cerr << "Usage: kopfstand in out" << std::endl;
        return -1;
    }

    if ((fd_in = open(argv[1],O_RDONLY)) == -1){
        perror("open");
        return -1;
    }

    if ((fd_out = open(argv[2],O_WRONLY|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR)) == -1){
        close(fd_in);
        perror("open");
        return -1;
    }


    fstat(fd_in, &sb);
    length = sb.st_size;
    map_size = sysconf(_SC_PAGESIZE);
    rest = length % map_size;
    offset = length -rest;

    if(rest != 0){
        addr = (char*)mmap(NULL, rest, PROT_READ, MAP_PRIVATE, fd_in, offset);
        if(addr == MAP_FAILED){
            perror("Error mmaping the File");
        }

        for (int off = rest-1;  off >= 0; --off){
            TRY(write(fd_out, addr+off, 1),"write");
        }

        if(munmap((char*)addr, rest)== -1){
            perror("munmap");
        }
    }


    while(offset > 0){
        offset =- map_size;

        addr = (char*)mmap(NULL, map_size, PROT_READ, MAP_SHARED, fd_in, offset);
        if(addr == MAP_FAILED){
            perror("Error mmaping the File");
        }
        for(int off = map_size-1; off >= 0; --off){
           TRY(write(fd_out, addr+off, 1),"write");
        }   


        if(munmap((char*)addr, map_size) == -1){
           perror("munmap");
        }   
    }

    close(fd_in);
    close(fd_out);

    return 0;
}
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278

1 Answers1

0

You're going to kick yourself! (I kicked myself when I finally spotted the problem!)

This line:

    offset =- map_size;

should be:

    offset -= map_size;

See also What does =+ mean in C?

One of the comments to the question by Andrew Medico observes that clang identifies the problem immediately — and it does:

$ clang -O3 -g -std=c++11 -Wall -Wextra -Werror badadd.cpp -o badadd
    badadd.cpp:65:16: error: use of unary operator that may be intended as compound assignment (-=)
          [-Werror]
            offset =- map_size;

G++ (GCC) 4.9.1 (home-built on Mac OS X 10.9 and running on 10.10.1) with the same compiler options does not identify the problem.

JFTR: I found the problem the hard way (with print statements tracing the value of offset), and only read Andrew's comment after finding and posting the answer.

Community
  • 1
  • 1
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • `clang` (from Xcode 6.1) prints the warning even in its default invocation (with no extra warning switches). – nobody Dec 03 '14 at 04:35
  • @AndrewMedico: interesting — I'm surprised that it is a common enough problem to warrant the analysis. The C compilers that supported `=-` (and `=+`, etc) were obsolete before about 1980. I think it is the first time I've seen the issue reported on SO (but I've not looked at every C and C++ question to make sure). – Jonathan Leffler Dec 03 '14 at 04:40
  • ohh man, i´m kicking myself so hard right now. i was awake until 5am because of this! Thanks for your help – BaronVonBullshitRidesAgain Dec 03 '14 at 13:43