I know this has been discussed here plenty of times, but I simply cannot see what I'm doing wrong. Here's the snippet.
#include <stdio.h>
#include <stdlib.h>
double** SEG = NULL;
void main ()
{
int i;
int seg_counter = 0;
SEG = (double**) malloc(1 * sizeof(double *));
for(i=0; i < 1; i++)
{
*(SEG + i) = (double*) malloc(9 * sizeof(double));
}
while (1)
{
SEG = (double**) realloc(SEG, seg_counter+1 * sizeof(double *));
for(i=seg_counter; i < seg_counter+1; ++i)
{
*(SEG + i) = (double*) malloc(9 * sizeof(double));
}
printf ("%d\n", seg_counter);
seg_counter++;
}
}
The goal is to add one row each time the loop is executed. I'm getting a memory error instead.
Thnx for any help here!
You do not have a 2D array only an array of pointers. You can have real 2D if you use array pointers.
Do not use types only objects in the sizeof
void *addRow(size_t *rows, const size_t cols, double (*array)[cols])
{
array = realloc(array, (*rows + 1) * sizeof(*array));
if(array) *rows += 1;
return array;
}
int main(void)
{
size_t cols = 10, rows = 0;
double (*array)[cols] = NULL;
for(size_t i = 0; i < 10; i ++)
{
void *tmp;
tmp = addRow(&rows, cols, array);
if(tmp)
{
array = tmp;
printf("Added another row!!!!! Rows = %zu\n", rows);
}
}
free(array);
}
You can also add some checks.
void *addRow(size_t *rows, const size_t cols, double (*array)[*rows])
{
if(rows && cols)
{
array = realloc(array, (*rows + 1) * sizeof(*array));
if(array) *rows += 1;
}
return array;
}
For starters you should set the variable seg_counter to 1 after this memory allocation
int seg_counter = 0;
SEG = (double**) malloc(1 * sizeof(double *));
++seg_counter;
Or you could write
int seg_counter = 1;
SEG = (double**) malloc( seg_counter * sizeof(double *));
Then the following for loop (that is in fact redundant) will look like
for(i=0; i < seg_counter; i++)
{
*(SEG + i) = (double*) malloc(9 * sizeof(double));
}
This statement
SEG = (double**) realloc(SEG, seg_counter+1 * sizeof(double *));
has a typo, You need to write
SEG = (double**) realloc(SEG, ( seg_counter+1 ) * sizeof(double *));
Again the next for loop is redundant. You could just write
*(SEG + seg_counter) = (double*) malloc(9 * sizeof(double));
and then
seg_counter++;
printf ("%d\n", seg_counter);
As you have an infinite while loop then your program will be aborted when memory can not be allocated.
Related
Allocations :
cell **initBoard(int boardSize)
{
int i, j, k;
cell **matrix;
matrix = (cell **) malloc((boardSize + 1) * sizeof(cell *));
// init upper frame
matrix[0] = (cell *) malloc((boardSize + 1) * sizeof(cell));
matrix[0][0].type = (char *) malloc(3 * sizeof(char));
matrix[0][0].type[0] = ' ';
for (k = 1; k <= boardSize; k++)
{
// +1 for null char ?
matrix[0][k].type = (char *) malloc(3 * sizeof(char));
matrix[0][k].type = arrNo[k - 1];
}
// init inner rows
for (i = 1; i <= boardSize; i++)
{
matrix[i] = (cell *) malloc((boardSize + 1) * sizeof(cell));
// first letter each row
matrix[i][0].type = (char *) malloc(3 * sizeof(char));
matrix[i][0].type[0] = (char) (BASE_ALPHABET + i);
// init cols
for (j = 1; j <= boardSize; j++)
{
matrix[i][j].type = (char *) malloc(2 * sizeof(char) + 1);
matrix[i][j].type[0] = EMPTY;
matrix[i][j].type[1] = WATER; // default status
matrix[i][j].hidesShip = NULL;
}
}
return matrix;
}
Deallocations :
void freeMatrix(cell **matrix, int boardSize)
{
int k, l;
for (k = 0; k <= boardSize; k++)
{
for (l = 0; l <= boardSize; l++)
{
free(matrix[k][l].type);
}
free(matrix[k]);
}
free(matrix);
}
I run the code above(malloc + free are showed) and then checked memory-leak with Valgrind and got this output :
Valdrind Log
Any idea what I am doing wrong here? The Valgrind means I did one extra free command? I cant see where exactly because I moved over all cells.. maybe better understanding of pointers is required here? thanks.
matrix[0][k].type = (char *) malloc(3 * sizeof(char));
matrix[0][k].type = arrNo[k - 1];
The problem is that you are allocating memory and immidiatly after you write to the pointer holding the address. You can no longer access the memory therefore valgrind reports it as leaked.
You probably wanted to write
matrix[0][k].type[0] = arrNo[k - 1];
Assuming that arrNo is a character array, the first assignment would be illegal since you are assigning char to char *. Your compiler should have given you a warning.
I'm using an example from https://phoxis.org/2012/07/12/get-sorted-index-orderting-of-an-array/ where he returns the sort indices from a sort of an array, i.e.
3,4,2,6,8 returns 4,3,1,0,2 (+1 for each index in R). This is the equivalent of R's order function
I've translated his/her code to work as a function returning an array of sorted indices. The code gives the correct answer.
keeping track of the original indices of an array after sorting in C has a similar response, but as #BLUEPIXY warns, his solution doesn't work in all circumstances. I need something that will work in all circumstances, including ties.
however, the original author uses a global pointer, which causes a memory leak, and free() doesn't fix it. which I don't know how to do this without the global pointer.
How can I fix this memory leak, or at least return sorted indices in C that will always work?
#include <stdio.h>
#include <stdlib.h>
/* holds the address of the array of which the sorted index
* order needs to be found
*/
int * base_arr = NULL;
/* Note how the compare function compares the values of the
* array to be sorted. The passed value to this function
* by `qsort' are actually the `idx' array elements.
*/
static int compar_increase (const void * a, const void * b) {
int aa = *((int * ) a), bb = *((int *) b);
if (base_arr[aa] < base_arr[bb]) {
return 1;
} else if (base_arr[aa] == base_arr[bb]) {
return 0;
} else {
// if (base_arr[aa] > base_arr[bb])
return -1;
}
}
int * order_int (const int * ARRAY, const size_t SIZE) {
int * idx = malloc(SIZE * sizeof(int));
base_arr = malloc(sizeof(int) * SIZE);
for (size_t i = 0; i < SIZE; i++) {
base_arr[i] = ARRAY[i];
idx[i] = i;
}
qsort(idx, SIZE, sizeof(int), compar_increase);
free(base_arr); base_arr = NULL;
return idx;
}
int main () {
const int a[] = {3,4,2,6,8};
int * b = malloc(sizeof(int) * sizeof(a) / sizeof (*a));
b = order_int(a, sizeof(a) / sizeof(*a));
for (size_t i = 0; i < sizeof(a)/sizeof(*a); i++) {
printf("b[%lu] = %d\n", i, b[i]+1);
}
free(b); b = NULL;
return 0;
}
A straightforward approach without using a global variable can look the following way
#include <stdio.h>
#include <stdlib.h>
int cmp_ptr(const void *a, const void *b)
{
const int **left = (const int **)a;
const int **right = (const int **)b;
return (**left < **right) - (**right < **left);
}
size_t * order_int(const int *a, size_t n)
{
const int **pointers = malloc(n * sizeof(const int *));
for (size_t i = 0; i < n; i++) pointers[i] = a + i;
qsort(pointers, n, sizeof(const int *), cmp_ptr);
size_t *indices = malloc(n * sizeof(size_t));
for (size_t i = 0; i < n; i++) indices[i] = pointers[i] - a;
free(pointers);
return indices;
}
int main( void )
{
const int a[] = { 3,4,2,6,8 };
const size_t N = sizeof(a) / sizeof(*a);
size_t *indices = order_int(a, N);
for (size_t i = 0; i < N; i++) printf("%d ", a[indices[i]]);
putchar('\n');
free(indices);
return 0;
}
The program output is
8 6 4 3 2
As for the memory leak then it is due to overwriting the value of the pointer to redundantly allocated memory.
int * b = malloc(sizeof(int) * sizeof(a) / sizeof (*a));
b = order_int(a, sizeof(a) / sizeof(*a));
The memory allocation does not make sense.
The problem I see is that within main function - you are allocating pointer b some memory -
int * b = malloc(sizeof(int) * sizeof(a) / sizeof (*a));
The next line calls order_int(...) that returns a pointer to already allocated memory -
b = order_int(a, sizeof(a) / sizeof(*a));
Looking at the order_int function -
int * order_int (const int * ARRAY, const size_t SIZE) {
int * idx = malloc(SIZE * sizeof(int));
base_arr = malloc(sizeof(int) * SIZE);
for (size_t i = 0; i < SIZE; i++) {
base_arr[i] = ARRAY[i];
idx[i] = i;
}
qsort(idx, SIZE, sizeof(int), compar_increase);
free(base_arr); base_arr = NULL;
return idx;
}
.. you see that idx has been already been allocated the correct memory.
I would suggest removing the malloc from b - see below.
int * b = NULL;
I have this struct called Grid that holds a 2d array of strings. I'v been searching on how to free multidimensional arrays properly and can't seem to find the problem with this procedure as valgrind keeps detecting errors and leaked memory. Thanks in advance!
typedef struct Grid{
int N;
int M;
char ***adj;
}TGrid;
TGrid* emptyGrid(int N, int M){
int i,j;
TGrid *Grid = malloc(sizeof(TGrid));
Grid->N = N;
Grid->M = M;
Grid->adj = malloc(N * sizeof(char ***));
for(i = 0; i < N; i++){
Grid->adj[i] = malloc(M * sizeof(char **));
for(j = 0; j < M; j++){
Grid->adj[i][j] = malloc(10 * sizeof(char *));
}
}
return Grid;
}
void freeGrid(TGrid *Grid){
int i, j;
for(i = 0; i < Grid->N; i++){
for(j = 0; j < Grid->M; j++){
free(Grid->adj[i][j]);
}
free(Grid->adj[i]);
}
free(Grid->adj);
free(Grid);
}
The way you malloc memory is incorrect, proper ways should be:
TGrid* emptyGrid(int N, int M){
int i,j;
TGrid *Grid = malloc(sizeof(TGrid));
Grid->N = N;
Grid->M = M;
Grid->adj = malloc(N * sizeof(char **));
for(i = 0; i < N; i++){
Grid->adj[i] = malloc(M * sizeof(char *));
for(j = 0; j < M; j++){
Grid->adj[i][j] = malloc(10 * sizeof(char));
}
}
return Grid;
}
Note that, Grid->adj[i][j] always points to array of 10 char, you can use this:
#include <stdio.h>
#include <stdlib.h>
typedef struct Grid{
int N;
int M;
char (**adj)[10];
}TGrid;
TGrid* emptyGrid(int N, int M){
int i;
TGrid *Grid = malloc(sizeof(TGrid));
Grid->N = N;
Grid->M = M;
Grid->adj = malloc(N * sizeof(char (*)[10]));
for(i = 0; i < N; i++){
Grid->adj[i] = malloc(M * sizeof(char[10]));
}
return Grid;
}
void freeGrid(TGrid *Grid){
int i;
for(i = 0; i < Grid->N; i++){
free(Grid->adj[i]);
}
free(Grid->adj);
free(Grid);
}
int main() {
TGrid* t = emptyGrid(2,3);
freeGrid(t);
return 0;
}
However, since free receives a void* parameter, there must be something else in your code.
The general structure of your code is fine, but the types under sizeof are wrong. The general idiom for malloc-ing memory looks as follows
T *p = malloc(N * sizeof *p);
or, equivalently
T *p = malloc(N * sizeof(T));
Note that in the latter (type-based) variant there's one less asterisk under sizeof than there's is in the recipient pointer type.
That's exactly how it should be in your case as well
Grid->adj = malloc(N * sizeof(char **));
/* Since `Grid->adj` is `char ***`, you should have `char **` under `sizeof` */
...
Grid->adj[i] = malloc(M * sizeof(char *));
/* Since `Grid->adj[i]` is `char **`, you should have `char *` under `sizeof` */
...
Grid->adj[i][j] = malloc(10 * sizeof(char));
/* Since `Grid->adj[i][j]` is `char *`, you should have `char` under `sizeof` */
If that's not what you need, then there must be something wrong with your types. There's no way to say without knowing your intent.
(And I would suggest you use the first approach to specifying sizeof under malloc - use expressions, not types. That way you won't have to count asterisks.)
However, in real life this specific error would typically only result in over-allocated memory. No out-of-bound access or memory leaks should occur. If valgrind reports such errors, there must be something else at work here as well.
It's difficult to see where the problem is since you haven't posted the code that uses the functions.
I want to point out that the calls to malloc need to be changed.
You have:
Grid->adj = malloc(N * sizeof(char ***));
for(i = 0; i < N; i++){
Grid->adj[i] = malloc(M * sizeof(char **));
for(j = 0; j < M; j++){
Grid->adj[i][j] = malloc(10 * sizeof(char *));
}
}
Those calls need to be changed to:
Grid->adj = malloc(N * sizeof(char **));
for(i = 0; i < N; i++){
Grid->adj[i] = malloc(M * sizeof(char *));
for(j = 0; j < M; j++){
Grid->adj[i][j] = malloc(10 * sizeof(char));
}
}
You can avoid such errors by using a coding style as follows:
Grid->adj = malloc(N * sizeof(*(Grid->adj)));
for(i = 0; i < N; i++){
Grid->adj[i] = malloc(M * sizeof(*(Grid->adj[i])));
for(j = 0; j < M; j++){
Grid->adj[i][j] = malloc(10 * sizeof(*(Grid->adj[i][j])));
}
}
A simpler case that uses the same style:
char* cp = malloc(10*sizeof(*cp));
You are not allocating arrays, you are allocating pointer-based look-up tables. The only reason for doing so is if you wish the individual dimensions to have different lengths (such as in an array of strings). If you don't need that, you should never use pointer-to-pointer tables since they are slow, error-prone and needlessly complex.
To allocate an actual 3D array, you would do like this:
char (*array)[Y][Z] = malloc ( sizeof(char[X][Y][Z] );
...
free(array);
To allocate an array of strings, you would do like this:
char** lookup = malloc ( sizeof( char*[N] ) );
for(size_t i=0; i<N; i++)
{
lookup[i] = ...; // assign pointers to strings
}
...
free(lookup);
As a rule of thumb, whenever your program contains more than two levels of indirection, the program design is most likely bad.
I need to fill sparse matrix with random elemnts. I am trying to get random elements and write them as value, column and row elements of their arrays but I keep running into segmentation faults.
This only happens if I set N=1000 then SIZE=10000 (because if I set SIZE=1000 or less, it works).
Does that mean I can't allocate all this memory or access it after I allocated it?
What should I do if I really need to get all this memory (SIZE=10'000) allocated? can someone please help me?
#include <stdio.h>
#include <stdlib.h>
typedef struct _matrix {
int size; //number of not-null elements
int ord; //order of matrix
int* val;
int* col;
int* row;
} matrix;
matrix init (int ord, int size)
{
matrix m;
m.ord = ord;
m.size = size;
m.val = malloc(sizeof(int) * size);
m.val = malloc(sizeof(int) * size);
m.val = malloc(sizeof(int) * size);
return m;
}
matrix fill_matrix (int ord)
{
int i, j, gap, size = ord * ord / 100;
matrix new_matrix = init(ord, size);
j = 1;
for (i = 0; i < size; i++) {
new_matrix.val[i] = rand() % 9 + 1;
new_matrix.col[i] = rand() % ord + 1; //<------SEGFAULT
new_matrix.row[i] = rand() % ord + 1;
j++;
}
return new_matrix;
}
int main()
{
matrix A;
int n = 1000;
A = fill_matrix(n);
return 0;
}
You assign to val three times, but never initialize the other two pointers.
m.val = malloc(sizeof(int) * size);
m.val = malloc(sizeof(int) * size);
m.val = malloc(sizeof(int) * size);
I'm guessing you meant this:
m.val = malloc(sizeof(int) * size);
m.col = malloc(sizeof(int) * size);
m.row = malloc(sizeof(int) * size);
m.val = malloc(sizeof(int) * size);
m.val = malloc(sizeof(int) * size);
m.val = malloc(sizeof(int) * size);
You never malloc m.col and m.row :-) Cut & Paste programming is evil...
I want to write a function in C language which returns the 2 dimension array to my main function.
A function that returns a dynamically allocated two dimensional array for the int type.
int ** myfunc(size_t width, size_t height)
{
return malloc(width * height * sizeof(int));
}
It has to be deleted with free once it is not used anymore.
EDIT This only allocates the space for the array which could be accessed by pointer arithmetic but unfortunately not by the index operators like array[x][y].
If you want something like this here is a good explanation. It boils down to something like this:
int ** myfunc(size_t ncolumns, size_t nrows)
{
int **array;
array = malloc(nrows * sizeof(int *));
for(i = 0; i < nrows; i++)
{
array[i] = malloc(ncolumns * sizeof(int));
}
}
You can not simply return malloc( x * y * sizeof(type) );
This will produce a segmentation fault when you try to index the array as a 2 dimensional array.
int **a = malloc(10 * 10 * sizeof(int));
a[1][0] = 123;
a[0][1] = 321;
The result of the above: Segmentation fault
You need to first create an array of pointers with c/malloc() then iterate this array of pointers and allocate space for the width for each of them.
void *calloc2d(size_t x, size_t y, size_t elem_size) {
void **p = calloc(y, sizeof(void*));
if(!p) return NULL;
for(int i = 0; i < y; i++) {
p[i] = calloc(x, elem_size);
if(!p[i]) {
free2d(y, p);
return NULL;
}
}
return (void*)p;
}
And free
void free2d(size_t y, void *matrix) {
if(!matrix) return;
void **m = matrix;
for(int i = 0; i < y; i++) {
if(m[i]) free(m[i]);
}
free(m);
return;
}
It should be simple i guess...
char **functioName(char param[][20])
{
char[][20] temp = malloc(20 * 20 * sizeof char);
//processing
return temp
}
If you know the size of the array, you can do so:
int (*myfunc())[10] {
int (*ret)[10]=malloc(10*10*sizeof(int));
return ret;
}
This function return pointer to 10 arrays of 10 ints.
Of course, you should use it as it is, and don't forget to free it after using.