Copy pointer array to NSData and then to pointer array - iphone

I have a problem with understand some basics. I want create pointer array (a1) copy it to NSData (c1) than again create pointer array (b1) from NSData and check if content of a1 and b1 is the same.
But I face with two erors:
First is "incorrect checksum for freed object" when I want create NSData dataWithBytes:length:
Second bytes in a1 and b1 aren't the same.
Could someone tell me why? For record I use xcode5 with arc.
- (void) testCopyBuffer {
int const bufferSize =4096;
int* a1;
a1 = (int*)malloc(bufferSize);
for (int i=0; i<bufferSize; i++) {
a1[i] = i;
}
NSData *c1 = [NSData dataWithBytes:a1 length:bufferSize];
int* b1;
b1 = malloc(bufferSize);
[c1 getBytes:b1 length:bufferSize];
for (int i=0; i<bufferSize; i++) {
XCTAssertTrue(a1[i]==b1[i], "Powinny być takie same");
}
}

You don't allocate the right amount of memory.
For bufferSize number of ints, you need to allocate
a1 = malloc(bufferSize * sizeof(int));
And later consequently
NSData *c1 = [NSData dataWithBytes:a1 length:(bufferSize * sizeof(int))];
etc. In your case,
for (int i=0; i<bufferSize; i++) {
a1[i] = i;
}
writes beyond the allocated memory, which can lead to all kinds of undefined
behaviour.

Related

How to store int in char * in iphone

Can anyone help converting the Int to char array
as i have buffer as
char *buffer = NULL;
int lengthOfComponent = -1;
char *obj;
buffer[index]= (char *)&lengthOfComponent;
if i do this it is thorwing EXCESS BAD ACCESS after the execution how to store the value of the obj to buffer using memcpy
Of course you cannot write in buffer[index], it is not allocated!
buffer = malloc(sizeof(char) * lengthOfBuffer);
should do it. After that you can write the buffer with memcpy or with an assignation, like you are doing.
buffer[index] = (char *)&lengthOfComponent;
buffer[index] is like dereferencing the pointer. But buffer is not pointing to any valid location. Hence the runtime error.
The C solution is using snprintf. Try -
int i = 11;
char buffer[10];
snprintf(buffer, sizeof(buffer), "%d", i);

Xor between 2 NSString gives wrong result

I have this method to make a xor between 2 NSStrings, i´m printing the result on NSLog but it isn´t the expect.
Can´t figure out what i´m doing wrong.
(void)XorSecretKeyDeviceId
{
NSString* secretKey = #"123";//
NSString* deviceId = #"abcdef";//
NSData* stringKey = [secretKey dataUsingEncoding:NSUTF8StringEncoding];
NSData* stringDeviceId = [deviceId dataUsingEncoding:NSUTF8StringEncoding];
unsigned char* pBytesInput = (unsigned char*)[stringKey bytes]; //Bytes
unsigned char* pBytesKey = (unsigned char*)[stringDeviceId bytes];
unsigned int vlen = [secretKey length]; //Keys Length
unsigned int klen = [deviceId length];
unsigned int v;
unsigned int k = vlen % klen;
unsigned char c;
for(v = 0; v < vlen; v++)
{
c = pBytesInput[v] ^ pBytesKey[k];
pBytesInput[v] = c;
NSLog(#"%c", c);
k = (++k < klen ? k : 0);
}
}
Are you setting your pBytesInput and pBytesKey variables correctly? At the moment, you have unsigned char* pBytesInput = (unsigned char*)[stringKey bytes]; (i.e. the input is the "key"), and pBytesKey is the device ID. This seems odd.
Also, be careful using UTF-8 encoding. UTF-8 uses the high bit on any byte in the string to indicate a "continuation" of a multi-byte character into the next byte. Your encoding could plausibly generate invalid UTF-8 by giving the setting the high bit of the final byte in the encryption.
For more than that, you'll have to say what the "wrong result" is.

How to do comparisons of bitmaps in iOS?

I have three CGLayers who's data I'd like to compare.
void *a = CGBitmapContextGetData(CGLayerGetContext(layerA));
void *b = CGBitmapContextGetData(CGLayerGetContext(layerB));
void *c = CGBitmapContextGetData(CGLayerGetContext(layerC));
I'd like to get a result like ((a OR b) AND c) where only bits that are on in layerA or layerB and also on in layerC end up in the result. These layers are kCGImageAlphaOnly so they are only 8 bits "deep", and I've only drawn into them with 1.0 alpha. I also don't need to know where the overlap lies, I just need to know whether there are any bits on in the result.
I'm really missing QuickDraw today, it had plenty of bit-oriented operations that were very speedy. Any thoughts on how to accomplish something like this?
Here's a naive implementation, assuming all three are the same size:
unsigned char *a = CGBitmapContextGetData(CGLayerGetContext(layerA));
unsigned char *b = CGBitmapContextGetData(CGLayerGetContext(layerB));
CGContextRef context = CGLayerGetContext(layerC);
unsigned char *c = CGBitmapContextGetData(context);
size_t bytesPerRow = CGBitmapContextGetBytesPerRow(context);
size_t height = CGBitmapContextGetHeight(context);
size_t len = bytesPerRow * height;
BOOL bitsFound = NO;
for (int i = 0; i < len; i++) {
if ((a[i] | b[i]) & c[i]) { bitsFound = YES; break; }
}
Since you're hankering for QuickDraw, I assume you could have written that yourself, and you know that will probably be slow.
If you can guarantee the bitmap sizes, you could use int instead of char and operate on four bytes at a time.
For more serious optimization, you should check out the Accelerate framework.
What about the CGBlendModes? kCGBlendModeDestinationOver acts as OR for A and B, and then you can use kCGBlendModeDestinationIn to AND that result with C.

iPhone - parsing nsdata to get multiple files stored there

I'm trying to find the new line and returns that are inside an nsdata object that I'm parsing . Here's some code:
uint8_t *arr = [receivedData bytes];
NSUInteger begin1 = 0;
NSUInteger end1 = len;
uint8_t *arr1 = (Byte *)malloc(sizeof(Byte)*((end1-begin1+1)));
int j = 0;
for (int i = begin1; i < end1; i++){
arr1[j] = arr[i];
j++;
if (arr[i] == 10) NSLog(#"---new line code---"); //edit: working - data was a problem
}
I just need to know when I hit a new line or return.
Thank You.
That certainly looks correct. Are you certain that the data you're parsing has newlines? Could it be a /r instead of a /n? If you can, try using the debugger and step through to see what the values actually are, and compare with what you expect them to be, to make sure they are correct.

How to sort a string of characters in objective-C?

I'm looking for an Objective-C way of sorting characters in a string, as per the answer to this question.
Ideally a function that takes an NSString and returns the sorted equivalent.
Additionally I'd like to run length encode sequences of 3 or more repeats. So, for example "mississippi" first becomes "iiiimppssss", and then could be shortened by encoding as "4impp4s".
I'm not expert in Objective-C (more Java and C++ background) so I'd also like some clue as to what is the best practice for dealing with the memory management (retain counts etc - no GC on the iphone) for the return value of such a function. My source string is in an iPhone search bar control and so is an NSString *.
int char_compare(const char* a, const char* b) {
if(*a < *b) {
return -1;
} else if(*a > *b) {
return 1;
} else {
return 0;
}
}
NSString *sort_str(NSString *unsorted) {
int len = [unsorted length] + 1;
char *cstr = malloc(len);
[unsorted getCString:cstr maxLength:len encoding:NSISOLatin1StringEncoding];
qsort(cstr, len - 1, sizeof(char), char_compare);
NSString *sorted = [NSString stringWithCString:cstr encoding:NSISOLatin1StringEncoding];
free(cstr);
return sorted;
}
The return value is autoreleased so if you want to hold on to it in the caller you'll need to retain it. Not Unicode safe.
With a bounded code-set, radix sort is best:
NSString * sortString(NSString* word) {
int rads[128];
const char *cstr = [word UTF8String];
char *buff = calloc([word length]+1, sizeof(char));
int p = 0;
for(int c = 'a'; c <= 'z'; c++) {
rads[c] = 0;
}
for(int k = 0; k < [word length]; k++) {
int c = cstr[k];
rads[c]++;
}
for(int c = 'a'; c <= 'z'; c++) {
int n = rads[c];
while (n > 0) {
buff[p++] = c;
n--;
}
}
buff[p++] = 0;
return [NSString stringWithUTF8String: buff];
}
Note that the example above only works for lowercase letters (copied from a specific app which needs to sort lowercase strings). To expand it to handle all of the ASCII 127, just do for(c=0; c <= 127; c++).