angerboy
angerboy

Reputation: 495

Objective C- Confusing EXC_BAD_ACCESS when using [NSString initwithdata]

I am having some trouble using the data that I receive from a remote server. This is how I take in the data from my nsinputstream:

 case NSStreamEventHasBytesAvailable:
    {
        if(!_data)
        {
            _data = [NSMutableData data];
        }

        uint8_t buffer = malloc(1024);
        NSInteger *len = [inputStream read:buffer maxLength:1024];
        if(len)
        {
            _data = [[NSData alloc]initWithBytesNoCopy:buffer length:1024];
            [self closeThread];
        }
        shouldClose = YES;

        break;
    }

In the same class I have this function to return the data in order to use it in different classes:

 -(NSData *)returnData {
      return self.data;
  }

In the view controller that I want to use the data in I have this code to retrieve the data for use:

 _schools = [_server returnData];
 NSString *schoolString = [[NSString alloc] initWithData:self.schools encoding:NSUTF8StringEncoding];//exc_bad_access

From what I understand about EXC_BAD_ACCESS exceptions they usually mean that you are trying to access data that either doesn't exist or is not allocated. The _schools variable shows a size of 1024 bytes so I know there is memory correctly allocated for it. Is there something else going wrong that I am missing?

Upvotes: 0

Views: 972

Answers (1)

CodaFi
CodaFi

Reputation: 43330

You appear to have mixed up the types of the variables on these two lines:

uint8_t buffer = malloc(1024);
NSInteger *len = [inputStream read:buffer maxLength:1024];

In its current form, you will malloc'ate 1024 bytes of memory, and attempt to store the pointer to said memory in a uint8_t (which CLANG will rightly scream at you for), thus truncating the pointer and not providing a buffer, but rather a single unsigned 8-bit byte for the stream to attempt to read into. Also, -[NSInputStream read:maxLength:] does not return NSInteger *, just plain NSInteger, so all you need to do is swap the pointers on the two variables:

uint8_t *buffer = malloc(1024);
NSInteger len = [inputStream read:buffer maxLength:1024];

and it should work just fine.

Upvotes: 1

Related Questions