0

I am currently writing a game in which I intend to transfer a .caf sound file from the iPhone to my C++ server. Right now I am getting an EXC_BAD_ACCESS when I message the sendGameUpdateWithFile function, and I really have no idea why.

Although this is not related to any uni assignments, please keep in mind that I am a CS student and not (yet) a professional network programmer, so judge my code thereafter.

Here's the code I use to transmit the data to the server (which crashes right now):

- (void) sendGameUpdateWithFile:(NSString*)filePath gameID:(NSInteger)gameID {
    NSMutableData* data = [[NSMutableData alloc] init];
    data = [NSMutableData dataWithContentsOfFile:filePath];

    fileheadPacket head;

    head.msgtype = 0x12;
    strncpy(head.data1, [myUsername cStringUsingEncoding:NSASCIIStringEncoding], [myUsername length]);
    int followingPackets = (([data length] % 1024 == 0) || ([data length] < 1024))? ([data length]/1024) : ([data length]/1024)+1;
    head.following = followingPackets;
    head.fileid = gameID;
    head.size = sizeof(packet);

    [mySock writeData:[NSData dataWithBytes:&head length:sizeof(packet)] withTimeout:-1 tag:7];

    filePacket sendPackets[followingPackets];

    for(int i = 0; i < followingPackets; i++){
        NSRange thisRange;
        thisRange.location = i*1024;
        thisRange.length = (i+1)*1024;

        filePacket tmp;
        tmp.msgtype = 0x13;
        tmp.size = sizeof(filePacket);
        memset(tmp.data1, 0, sizeof(tmp.data1));
        [data getBytes:tmp.fileBuffer range:thisRange];

        strncpy((char*)&sendPackets[i], (char*)&tmp, sizeof(tmp));
    }

    for(int i = 0; i < followingPackets; i++){
        [mySock writeData:[NSData dataWithBytes:&sendPackets[i] length:sizeof(filePacket)] withTimeout:-1 tag:3];
    }
}

The structs I use for data look like this:

typedef struct file_packet {
    int msgtype:8;
    int size:16;
    int nul:8;
    int following:24;
    int emp:8;
    char data1[64];
    char fileBuffer[1024];
} filePacket;

typedef struct filehead_packet {
    int msgtype:8;
    int size:16;
    int nul:8;
    int following:24;
    int emp:8;
    char data1[64];
    int fileid;
    char rest[60];
} fileheadPacket;

The server expects the given msgtypes -- the problem lies on the client side.

Cœur
  • 37,241
  • 25
  • 195
  • 267
Henrik Hillestad Løvold
  • 1,213
  • 4
  • 20
  • 46
  • Would you be able to post the crash log? What line does the bad access occur on. Also your first line creates a memory leak. NSMutableData* data = [[NSMutableData alloc] init]; creates an alloc'd object, which you then lose the reference to with data = [NSMutableData dataWithContentsOfFile:filePath]; which creates an autoreleased object – Bergasms Nov 27 '13 at 22:45
  • Hey Bergasms. I'd love to post a crash log, but the terminal simply states (lldb), and I get an arrow in my code with the text Thread1: EXEC_BAD_ACCES(code=1, address=0xfffffff0) at the last line of that function. Regarding the memleak: I've got ARC on my program. Since that pointer to data goes out of scope after the function has returned, I assume the data field is released by the ARC? – Henrik Hillestad Løvold Nov 27 '13 at 22:53
  • Please don't be offended... Have you placed breakpoints and nslogs to check information? How many iterations are done? Are they in a correct number? the processed and result values are within expected? – TtheT Nov 27 '13 at 23:11
  • I'm not offended at all! I've used breakpoints for the last hour, and it appears the for-loop is the problem. With the data with which I am testing, I get followingPackets = 16, which makes sense. The for-loop runs once, and once I enter it the second time, it crashes on the strncpy call. Before that everything's fine, but after calling strncpy all pointers go to nil, and all values to 0. Then I get the BAD_ACCESS stuff. Seems strange to me. – Henrik Hillestad Løvold Nov 27 '13 at 23:22
  • You're increasing `thisRange.length` with every iteration - shouldn't it remain 1024? Secondly, on the final iteration of the first loop, your call to `getBytes:range:` will probably barf because you're trying to read exactly `thisRange.length` bytes when probably < `thisRange.length` bytes of `data` remain. Finally, if you're copying binary data (which may contain NULLs) then you should use `memcpy()` instead of `strncpy()`. – Gary Chapman Nov 27 '13 at 23:50
  • regarding the memory leak i mentioned and ARC, you are correct, the line just threw my a little. Also, a tip with debugging. Make sure you are catching all the throws. press 'command-6', press the + in the bottom left and add an exception breakpoint to catch all. Secondly, after pressing 'command-5' make sure the slider at the bottom is all the way to the right, this can help reveal more information. – Bergasms Nov 28 '13 at 01:27
  • Finally, when you see the lldb command prompt, try hitting the play button (second button from the left at the top of the debug window) a few times to step the app forwards. this often produces a more detailed stack trace. – Bergasms Nov 28 '13 at 01:30

0 Answers0