Reputation: 1842
I have a small c++ programme that fails to allocate more than 2880 with malloc
. The statement:
void* tmpptr = malloc(2881);
crashes, whilst
void* tmpptr = malloc(2880);
does not. Every time!
I am using MinGW and compiling with
g++ -std=c++0x -pedantic -Wall -Wextra -g -D_GLIBCXX_DEBUG -static-libgcc -static-libstdc++
I know that the use of malloc
is discouraged in C++ and I am planning to rewrite this anyway, but I would still want to know why this is not working. The same code has been working when I compiled it with gcc.
Update: This is the main function calls:
image * img = readPPM("pic/pic.ppm");
bw_image * sky = skyline(img, ref);
cont * lin = contour(sky, 0); // <-- chash
...
And the function starts with:
#include <cstdlib>
cont * contour(const bw_image * img, const char wrap) {
int test = 2880;
void* ptr1 = malloc(test);
void* ptr2 = malloc(test);
...
Now the first malloc
will work but not the second one. If I change test = 1440;
, same result. But; for test = 140;
already the first malloc
will fail.
I've tried the code as a stand alone:
int main(int argc, char *argv[]) {
int size = 2881;
void* tmpptr;
printf("Allocating, %d\n", size);
tmpptr = malloc(size);
printf("Allocated %d bytes successfully\n", size);
}
and it works without problems, so it seems to be something in main
doing it.
rem_artifacts
look like this
void rem_artifacts(bw_image * sky) {
for (int y = 0; y < sky->y; ++y) for (int x = 0; x < sky->x; ++x) {
int xp = x - 1, xn = x + 1;
if (xp < 0) xp = sky->x - 1;
if (xn == sky->x) xn = 0;
int c = sky->data[x][y]; // this is wrong
if (
(y == 0 || sky->data[x][y-1] != c) && // and this
(y == sky->y-1 || sky->data[x][y+1] != c) && // and this
sky->data[xp][y] != c && // and this
sky->data[xn][y] !=c // and this
) sky->data[x][y] = !c; // and this
}
}
bw_image * skyline(const image * img, const image * ref) {
double tilt = 114.0 - 90.0;
double pi = 3.14159265358979323846;
double chang = 360.0 / 2.0 / pi;
//double sint = sin(tilt / chang);
//double cost = cos(tilt / chang);
bw_image * sky = (bw_image*)malloc(sizeof(bw_image));
sky->x = img->x;
sky->y = img->y; //
double cos30 = sqrt(3)/2;
int lim0 = (int)((double)(img->y) / 2.0 + (double)(img->x) * tan(tilt/chang) * cos30);
sky->data = (char**)malloc(sizeof(char*) * sky->y);
for (int y = 0; y < sky->y; ++y) {
sky->data[y] = (char*)malloc(sizeof(char) * sky->x);
for (int x = 0; x < sky->x; ++x)
sky->data[y][x] = !(y < lim0 && colour_dist_sq(img->data[y][x], ref->data[y][x]) < 5000.0);
}
rem_artifacts(sky);
return sky;
}
Upvotes: 2
Views: 1582
Reputation: 1842
Thank you everybody,
It turns out that I was writing outside the allocated memory (a bit of a x and y confusion). The weird thing is though that the programme has been working until now (24/7 for many months) and doing what I have been expecting of it. It could though explain some weird things I haven't been able to explain.
Now I will anyway rewrite the code with standard C++ memory allocation.
Upvotes: 2
Reputation: 409136
If I would venture a guess, it's that you don't properly allocate sky->data
or its sub-pointers.
This has to be done in two steps:
First allocate sky->data
:
sky->data = new char*[some_x_size];
Then you have to allocate all sub-array separately:
for (int x = 0; x < some_x_size; x++)
sky->data[x] = new char[some_y_size];
You can of course use malloc
instead of new
.
When freeing the data, you do it the opposite way: First free each sub-array in a loop, then the main array.
Upvotes: 0
Reputation: 96233
It looks to me like your heap is getting corrupted somewhere else in your program (probably during that big loop in main
. The first thing you can do is start turning on warnings -Wall
and -Wnon-virtual-dtor
at a very minimum and then fixing them.
If you have access to Linux your best bet is to run this under valgrind and be amazed as it tells you exactly where you're overwriting memory.
Alternately if you have access to Purify ($$$) on Windows that may be able to help you as well. There are also memory checking malloc libraries available you may be able to use.
If none of those tools are available you're going to have to do diagnostics yourself by trying to remove sections of code and see if it still crashes or not.
Upvotes: 0