First: Arrays in C start at 0, not 1. In your very first for() loop, i's max value is Row, or 4. You only allocated room for 4 rows however, and K1[i] = K1[Row] = K1[4] accesses the fifth item, which you never allocated memory for. (Since they start at zero, K1[0] = first row, K1[1] = second row, etc.) This happens a lot in your code.

Code:

printf("%d \t",K1[Row][Col]);

Why is that in a loop? Row and Col are constant in your function at that point... so that prints the same value each time. Which means you cannot be getting the output you posted, if I'm reading your code correctly.

Finally, your use of malloc / calloc / realloc. First, they all return void *s, so you do not (and should not) cast them. (Edit: Which dude543 didn't change) Your realloc's error handling also memory leaks - when realloc fails, it doesn't free the old memory. Something like:

You just need to ensure that actual doesn't become a memory leak - the above example could be modified to not free() actual if it is stored somewhere else, hence the user won't loose their data. All depends on you.

Oki code seems to work fine until you free K1 and K2, cause I think you are freeing it twice
Since

Code:

free() frees the memory space pointed to by ptr, which must have been
returned by a previous call to malloc(), calloc() or realloc(). Other-
wise, or if free(ptr) has already been called before, undefined behav-
iour occurs. If ptr is NULL, no operation is performed.

No. They're freeing the rows one at a time, then once you're done, you free the row holders. That is to say, you allocate the number of rows. Then you allocate each row's contents one chunk at a time. You free in reverse of this. Free each row's contents, then free the row pointers themselves.

No. They're freeing the rows one at a time, then once you're done, you free the row holders. That is to say, you allocate the number of rows. Then you allocate each row's contents one chunk at a time. You free in reverse of this. Free each row's contents, then free the row pointers themselves.

Quzah.

yep, folks at #c on freenode pointed me this out but the code still breaks, folks there said it might be a corrupted heap, I'm googling to learn how to use valgrind right now

No. They're freeing the rows one at a time, then once you're done, you free the row holders. That is to say, you allocate the number of rows. Then you allocate each row's contents one chunk at a time. You free in reverse of this. Free each row's contents, then free the row pointers themselves.

Quzah.

Yes and no. Yes, you're right, he does need to free one row at a time, then the row holders. (Like he's doing.) But what I think Maragato was getting at was the segments of code like:

Code:

free(K1);
free(K2);

And

Code:

free(K1[i]);
free(K2[i]);

He only ever uses K2 as a temporary holder for the result of realloc(), and then assigns it to K1 on success. Thus they point at the same data - looking at his code, K2 doesn't point to data that K1 doesn't, and thus doesn't need to be free'd.

wots_guge: Your realloc() calls need fixing: the second parameter is how much memory to allocate, but you're forgeting to multiply by the size of your type. realloc(K1[i],Col+2) should be realloc(K1[i], (Col + 2) * sizeof(int)) for example. (And be sure you check to use the right thing in the sizeof()... sizeof(int) != sizeof(int *) )
(Edit: commenting out the free's mentioned above and changing your reallocs gives me your expected output.)

wots_guge: Your realloc() calls need fixing: the second parameter is how much memory to allocate, but you're forgeting to multiply by the size of your type. realloc(K1[i],Col+2) should be realloc(K1[i], (Col + 2) * sizeof(int)) for example. (And be sure you check to use the right thing in the sizeof()... sizeof(int) != sizeof(int *) )
(Edit: commenting out the free's mentioned above and changing your reallocs gives me your expected output.)

Fantastic stuff, thanks Hugger It really kept me busy for a lot of time.. it works fine now!

> it works fine now!
Post it then.
This is a fairly tricky process, and my guess is that you've assigned "works" to "it's just stopped crashing".

Yes, it "seems" to be "working as expected". From VB experience, only last dimension of a multi-dimensional array can be expanded. I guess realloc also does the same, but probably we can use combinatin of realloc and calloc to expand it in multi-dimension.

As we can see in the output, the new allocated memory space using realloc has garbage from heap, and at rows where calloc was used it is initialized to zeros.

Since they are the same, your effort to avoid stamping on the old pointer fails.

There is no need to have a "temp" of the same type, you can just use a void* for your temp variable. Plus being void*, there's no chance of you accidentally trying to dereference it without the compiler getting upset.

And why are you still casting the return result of malloc functions?http://faq.cprogramming.com/cgi-bin/...&id=1043284351
If, without casts you're getting messages about assigning the result of malloc,
"cannot convert int to pointer" - means you forgot to include stdlib.h, so include it
"cannot convert void* to type*" - means you're using a C++ compiler to compile C, so switch to a C compiler.

> the new allocated memory space using realloc has garbage from heap
Correct - you need to clear the memory yourself.
There is no 'calloc' version of realloc.
In fact, using calloc can be a problem when you're trying to allocate 'initialised' pointers and/or floats (or structures containing them).http://www.eskimo.com/~scs/c-faq.com/malloc/calloc.html