PDA

View Full Version : malloc error




farmerdoug
Sep 19, 2012, 05:15 PM
This line

fileName.text = [NSString stringWithUTF8String: "EDGE.JPG"];

results in this error

loadimage(2884,0xac4e92c0) malloc: *** error for object 0x7282204: incorrect checksum for freed object - object was probably modified after being freed.
*** set a breakpoint in malloc_error_break to debug

help
thanks.



chown33
Sep 19, 2012, 05:53 PM
I don't know the reason for the malloc error, but it's a needless construct.

An Objective-C string literal would serve the purpose, and be both clearer and more concise:
fileName.text = @"EDGE.JPG";

farmerdoug
Sep 19, 2012, 06:03 PM
Thanks. Still learning the basics. However, I still get the same error. If I get the file name from the UITextField, there is no error but when I modified the code using fileName.text = @"EDGE.JPG" I get the error.



//
// Created by Douglas Brenner on 9/16/12.
// Copyright (c) 2012 Douglas Brenner. All rights reserved.
//

#import "ViewController.h"

@interface ViewController ()
@property (weak, nonatomic) IBOutlet UIImageView *myImage;
@end

@implementation ViewController


-(IBAction)loadimage:(id)sender {
// Name is already loaded
//NSLog(@"%@", fileName.text);

UIImage *raw = [UIImage imageNamed:fileName.text];
UIImage *image = [self imageWithGrayScaleImage:raw];
// CGRect myImageRect = CGRectMake(0.0f, 0.0f, 320.0f, 109.0f);
[_myImage setImage:image];
_myImage.opaque = YES; // explicitly opaque for performance

[self.view addSubview:_myImage];




}
-(void)serialloadimage {

fileName.text = @"EDGE.JPG";
UIImage *raw = [UIImage imageNamed:fileName.text];
UIImage *image = [self imageWithGrayScaleImage:raw];
// CGRect myImageRect = CGRectMake(0.0f, 0.0f, 320.0f, 109.0f);
[_myImage setImage:image];
_myImage.opaque = YES; // explicitly opaque for performance

[self.view addSubview:_myImage];

}

-(IBAction)close:(id)sender {

[fileName resignFirstResponder];
}

- (UIImage*)imageWithGrayScaleImage:(UIImage*)inputImg
{
//Creating image rectangle
//CGRect imageRect = CGRectMake(0, 0, inputImg.size.width / (CGFloat)[inputImg scale], inputImg.size.height / (CGFloat)[inputImg scale]);
CGRect imageRect = CGRectMake(0, 0, inputImg.size.width, inputImg.size.height);

//Allocating memory for pixels
int width = imageRect.size.width;
int height = imageRect.size.height;

uint32_t *pixels = (uint32_t*)malloc(width * height * sizeof(uint32_t));

//Clearing the memory to preserve any transparency.(Alpha)
memset(pixels, 0, width * height * sizeof(uint32_t));

//Creating a context with RGBA pixels
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate(pixels, width, height, 8, width * sizeof(uint32_t), colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedLast);

//Drawing the bitmap to the context which will fill the pixels memory
CGContextDrawImage(context, imageRect, [inputImg CGImage]);

//Indices as ARGB or RGBA
const int RED = 1;
const int GREEN = 2;
const int BLUE = 3;
uint32_t grayPixel;
uint8_t* rgbaPixel;
uint32_t *edge;
int *filterout;
int filter[10];
edge = (uint32_t*)calloc(height, sizeof(uint32_t));;
filterout = (int*)calloc(height, sizeof(int));
int i;
for(i = 0; i < 5; i++)
filter[i] = -1;
for(i = 5; i < 10; i++)
filter[i] = 1;

FILE *edgedata;
edgedata = fopen("/Users/doug/edge.txt","w");
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
rgbaPixel = (uint8_t*)&pixels[y * width + x];
//Calculating the grayScale value
grayPixel = 0.3 * rgbaPixel[RED] + 0.59 * rgbaPixel[GREEN] + 0.11 * rgbaPixel[BLUE];
//Setting the pixel to gray
rgbaPixel[RED] = grayPixel;
rgbaPixel[GREEN] = grayPixel;
rgbaPixel[BLUE] = grayPixel;
edge[x] += grayPixel;
}
}


for (int x = 0; x < width - 10; x++)
for(i = 0; i < 10; i++){
filterout[x+5] += filter[i]*(int)edge[x + i];
//printf("%d %d %\n", filterout[x+5], filter[i], edge[x])
}

for (int x = 0; x < width; x++)
fprintf(edgedata,"%d\n", filterout[x]);
fclose(edgedata);

//Creating new CGImage from the context with modified pixels
CGImageRef newCGImage = CGBitmapContextCreateImage(context);

//Releasing resources to free up memory
CGContextRelease(context);
CGColorSpaceRelease(colorSpace);
free(pixels);

//Creating UIImage for return value
//UIImage* newUIImage = [UIImage imageWithCGImage:newCGImage scale:(CGFloat)[inputImg scale] orientation:UIImageOrientationUp];
UIImage* newUIImage = [UIImage imageWithCGImage:newCGImage];

//Releasing the CGImage
CGImageRelease(newCGImage);

return newUIImage;
}
- (void)viewDidLoad
{

[self serialloadimage];
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}

- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
} else {
return YES;
}
}

@end

chown33
Sep 19, 2012, 06:51 PM
No one knows what 'fileName' is. You need to show its declaration.

If fileName is an object reference, you need to confirm your expectation that it's a valid object reference. I suggest setting a breakpoint in the debugger, and stepping through the code.

The problem could have nothing to do with the string literal, and everything to do with the validity of whatever fileName is.


If I had to guess, I'd guess this is wrong (at a minimum):
[self serialloadimage];
[super viewDidLoad];

In general, you should call the super method so things are properly set up, and only then call other methods which might require things to already be properly set up.

I recommend using the debugger with the malfunctioning code, so you can what's wrong. Then change it, and run again with the same breakpoint.

If you haven't written many iOS programs before, I suggest looking at Apple's sample code for known-working examples.

farmerdoug
Sep 19, 2012, 07:20 PM
@interface ViewController : UIViewController
{
IBOutlet UITextField *fileName;
}

-(IBAction)loadimage:(id)sender;

-(void)serialloadimage;
-(IBAction)close:(id)sender;
@end


If I comment this out
//fileName.text = @"EDGE.JPG";
the code runs just fine so I don't think it can be

[self serialloadimage];
[super viewDidLoad];


The original code did come from an example which I have been modifying towards my own end. For testing purposes, I want to be able to construct a file name and load the image.

----------

The original code used the IBAction methods. I then added the void serialloadimage.
I changed the declaration for fileName and commented out the IBAction code.

Problem solved.

----------

Now I removed all references to IBAction and the error is back.

farmerdoug
Sep 19, 2012, 07:48 PM
This does not produce any errors


NSLog(@"%@", @"here2");

//Drawing the bitmap to the context which will fill the pixels memory
CGContextDrawImage(context, imageRect, [inputImg CGImage]);


Commenting out the NSLog does.

chown33
Sep 20, 2012, 01:21 PM
This does not produce any errors


NSLog(@"%@", @"here2");

//Drawing the bitmap to the context which will fill the pixels memory
CGContextDrawImage(context, imageRect, [inputImg CGImage]);


Commenting out the NSLog does.
Post the actual error message. We can't see your screen.


If the error message is similar to your first post, have you done what it says? Specifically:
*** set a breakpoint in malloc_error_break to debug

Did you set a breakpoint there? Are you using the debugger?

farmerdoug
Sep 20, 2012, 01:42 PM
Haven't yet figured out how to use the debugger; using print statements and commenting out code, I have found out that the code runs find as long as it can get the file name from the Iphone window and runs into trouble when ever I try to bypass the window by assign fileName.text a name. The code also fails at different locations each time.
The error is always the same
loadimage(5172,0xac4e92c0) malloc: *** error for object 0xc1f2600: incorrect checksum for freed object - object was probably modified after being freed.

chown33
Sep 20, 2012, 03:40 PM
Break It Down.

Remove all the image-processing, file-writing, etc. in imageWithGrayScaleImage:. Not just some of it, all of it. Then see if the program still fails.

If it works, then start adding back parts of the image-processing, one small piece at a time. The minimum would probably be the creation and the freeing of the malloc'ed pixel buf. Just that. Repeat test to see if it fails.

Then see if adding back the creation of the CGImageRef (and its freeing works). No data yet, just create and free.

Continue adding back functionality until it breaks. Once it breaks, you know what code is causing the problem. The posted error message:
loadimage(5172,0xac4e92c0) malloc: *** error for object 0xc1f2600: incorrect checksum for freed object - object was probably modified after being freed.
strongly suggests that some malloc'ed buffer is being scribbled on. That might be after an actual free, or it might be because you're overflowing some malloc'ed buffer.

This is basic debugging and implementation. Write a small piece, test it. If it fails, fix that before proceeding. The principle is to always have something that doesn't fail, which serves as a base for building the next piece. It doesn't have to do much, it just can't fail.

If you try to make it all work monolithically, your chances for success are drastically lower, especially if you can't use a debugger to actually peer and poke at memory or variables, or use breakpoints to stop things and look at them. And you're never going to "figure out" the debugger unless you study it and practice using it, preferably for doing actual debugging. It's not a puzzle to figure out; it's a tool that needs to be practiced for effective use.

If you had factored out the major image processing in imageWithGrayScaleImage:, you could paste it into a command-line program then build and run it as a simple Mac program. This is a simple version of unit-testing, where you test functionality and debug it in a command-line environment, preferably using a debugger, then only use it in a GUI after it's known working.

farmerdoug
Sep 20, 2012, 04:23 PM
I've sort of done that. Going to try again.

SplitIt!
Sep 20, 2012, 05:00 PM
fileName.text = [NSString stringWithUTF8String: "EDGE.JPG"];


just use:


fileName.text = @"EDGE.JPG";

farmerdoug
Sep 20, 2012, 05:41 PM
Started pretty much from scratch; took out the text window on the iPhone; ran several times with no errors.

Thanks.

farmerdoug
Sep 21, 2012, 06:45 AM
problem back.

returned when I added the commented out code.

/* # define FILTER_SIZE 10
int filter[FILTER_SIZE], i;
for(i = 0; i< FILTER_SIZE/2; i++)
filter[i] = -1;
for(i = FILTER_SIZE/2; i < FILTER_SIZE; i++)
filter[i] = 1;

uint8_t* edge;
edge = (uint8_t*) calloc(height, sizeof(uint8_t));
int * filtered;
filtered = (int*)calloc(height, sizeof (int));
FILE *output;
output = fopen("/Users/doug/edge.txt", "w");
*/ for (y = 0; y < height; y++)
{
for (x = 0; x < width; x++)
{
uint8_t* rgbaPixel = (uint8_t*)&pixels[y * width + x];

//Calculating the grayScale value
uint32_t grayPixel = 0.3 * rgbaPixel[RED] + 0.59 * rgbaPixel[GREEN] + 0.11 * rgbaPixel[BLUE];

//Setting the pixel to gray
rgbaPixel[RED] = grayPixel;
rgbaPixel[GREEN] = grayPixel;
rgbaPixel[BLUE] = grayPixel;
// edge[x] += grayPixel;
}
}

/* for (x = 0; x < width - FILTER_SIZE; x++)
for(i = 0; i < FILTER_SIZE; i++)
filtered[x + FILTER_SIZE/2] += filter[i]*(int)edge[x+i];


for ( x = 0; x < width; x++)
fprintf(output,"%d\n",filtered[x]);
fclose(output);

farmerdoug
Sep 21, 2012, 08:22 AM
change edge from uint_8 to int and cast grayPixel to int
edge(x) = (int) grayPixel;

works.
why?

chown33
Sep 21, 2012, 10:40 AM
How many elements does edge point at? If you exceed that count, what happens? Same questions for filtered.

Look at your loops that store values into edge and filtered. What is the maximum index?

This would be the perfect opportunity to use the debugger to inspect the indexes.

mfram
Sep 21, 2012, 10:43 AM
The edge array looks like it's being allocated based on 'height'. But the array is being dereferenced by x which is a for loop over the width variable. Those values don't match up.

If height != width then there's definitely a bug there.

farmerdoug
Sep 21, 2012, 11:42 AM
A fresh set of eyes is always helpful.
thanks.