0

I have a huge NSMutableData object(approximately 1 MB in size) in memory and now I want to replace all the bytes in the object to 0 (not deallocate the memory). The resetBytesInRange method lets me do this. However how do I verify/check if the bytes are actually set to 0. I want to look at the memory addresses and confirm this. Is this possible?

I have the following code

NSMutableData *imgData = [NSMutableData dataWithCapacity:50000000];
imgData = (NSMutableData*)UIImageJPEGRepresentation(img, 1.0);
[imgData resetBytesInRange:NSMakeRange(0, [imgData length]) ];

Now when I look into the address pointed to by imgData (and the following few locations), before and after the resetBytes, I do not see any change in the values in the memory locations starting from the address pointd to by imgData (I expected to see zeros assigned). I assumed that the memory allocations are contiguous starting from the the address pointed to by imgData (upto [imgData length]). Is this assumption corerct (which seems like it is not)? If not where are the bytes in the NSMutableData object stored? Can I access them individually?

Thanks

Vivek

vivek
  • 41
  • 1
  • 6
  • Why do you want to waste cycles on this? Do you suspect there's a bug in Foundation? – Jonathan Grynspan Jun 28 '12 at 14:04
  • Part of the requirement for my piece of work is to explicitly set this to 0 and then verify this. That is the requirement and I am not looking at the issue of wasting cycles at the moment. I want to get this working first and then will look at the overheads – vivek Jun 28 '12 at 14:09

2 Answers2

0

imgData is a pointer (as indicated by the * symbol). So it points to a memory location and assignment will just change the location it points to. It's not really the intention of most programming languages to let you do byte-by-byte manipulation of actual memory locations.

Read this: http://www.cplusplus.com/forum/general/3644/

Dustin
  • 6,783
  • 4
  • 36
  • 53
  • Unfortunately as part of my requirement I need to reset bytes and verify the reset. Looks like the memory block for the bytes are not contiguous allocations otherwise I could just increment the pointer starting from the address pointed to by imgData. In this circumstance what would be the best approach? – vivek Jun 28 '12 at 14:16
  • I'm not sure how to do what you need in objective c, but you could try some C++. – Dustin Jun 28 '12 at 14:32
0

The problem is not that -resetBytesInRange: doesn't work. The problem is that you're sending that message to the wrong object.

imgData = (NSMutableData*)UIImageJPEGRepresentation(img, 1.0); doesn't assign the JPEG bytes to the mutable data you created in the first line. It replaces your reference to that object with a reference to a new object, and uses a cast to suppress the compiler warning about an invalid store. There are a few ways to do this properly:

NSMutableData *imgData = [NSMutableData data]; /* note, we do not specify a capacity--it's pointless for this use case */
[imgData setData: UIImageJPEGRepresentation(img, 1.0)];
[imgData resetBytesInRange: NSMakeRange(0, [imgData length])];

Or:

NSMutableData *imgData = [[UIImageJPEGRepresentation(img, 1.0) mutableCopy] autorelease];
[imgData resetBytesInRange: NSMakeRange(0, [imgData length])];

But both ignore the obvious: if you're immediately clearing the data to zero, why are you even bothering to create the JPEG data? What are you actually trying to do here?

Jonathan Grynspan
  • 43,286
  • 8
  • 74
  • 104
  • Look at his comment on my question... He wants to do direct manipulation of memory. If you know how to do that, I would love to hear the answer – Dustin Jun 28 '12 at 14:38
  • Take a look at `-[NSMutableData mutableBytes]`? – Jonathan Grynspan Jun 28 '12 at 14:46
  • I thought that stored pointers to memory locations, but not necessarily in a way that let you directly change the values - similar to string immutability, you'd have to change where the pointer was looking not the actual contents of the original memory location – Dustin Jun 28 '12 at 14:55
  • So I am now assuming that the memory allocation for NSMutableData takes place like linked lists. That makes sense as to why iteration fails while we try to look at consecutive memory locations. I haven't tried out what Jonathan said but I will do that and get back about it what happens. However the question of verification still remains. If we assume the linked list implementation then there should be something like a next pointer within the data structure of the NSMutableData to point to the next address. How do we access this? If we find this out we can iterate and verify if 0s are set. – vivek Jun 28 '12 at 15:10
  • No, an `NSData` represents a contiguous region of memory. – Jonathan Grynspan Jun 28 '12 at 15:11
  • I think you guys need to read the `NSData` and `NSMutableData` documentation a little more closely. – Jonathan Grynspan Jun 28 '12 at 15:12
  • I did read. Thanks for the tip. Let me make my problem statement more clear. I am trying to read an image from the disk, and bring the entire image into my program memory, view it from there and then reset all the bytes to 0 and then deallocate it. So in my case I want the picture in memory and stored while accessing it using NSMutableData. Now after displaying when I want to clear it I want to access the image(which right now is in my program memory) using the NSMutableData pointer and set 0 to all the bytes that was occupied by the image in my program memory. Hope this helps. – vivek Jun 28 '12 at 15:32
  • Also I would like to know which memory locations I should look at in the debugger to verify the setting of zeros. Later when I set it to a non zero number(lets say 1) I want to verify that too. Thanks – vivek Jun 28 '12 at 15:48
  • Hi Jonathan.. I am still finding trouble in viewing this contiguous block of memory to check if the bytes are reset to 0. During debugging I am looking at the memory of imgData (as opposed to memory of *imgData) but I don't see the 0s being assigned. Am i looking at the right address? If not which address should I look at. Thanks – vivek Jun 28 '12 at 17:30
  • As I *already said*, you get access to the raw bytes with `-[NSMutableData mutableBytes]`. The `NSData` object itself acts as a handle to the data, but it is not directly the bare pointer. – Jonathan Grynspan Jun 28 '12 at 17:37