0

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!

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
argeus
  • 13
  • 2
  • 1
    Why realloc in an infinite loop? This is doomed to fail. – ggorlen Oct 05 '22 at 17:59
  • `for(i=0; i < 1; i++)` only executes one iteration. Why use a loop at all? – Barmar Oct 05 '22 at 18:00
  • Welcome to Stack Overflow! [don't cast malloc](https://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc) – Barmar Oct 05 '22 at 18:00
  • 1
    Using `*(SEG + i)` is harder to write and read than `SEG[i]`. – Jonathan Leffler Oct 05 '22 at 18:01
  • 1
    `for(i=seg_counter; i < seg_counter+1; ++i)` also only executes once. Again, why use a loop for just one iteration? – Barmar Oct 05 '22 at 18:01
  • *`A 2D array reallocation in C`* - no, I do not see any 2D arrays here – 0___________ Oct 05 '22 at 18:05
  • Gents, thank you indeed, you saved my day. The simple typo was a problem. The final loop will not be infinite, I used it just for demonstration purposes. I made some simplifications you proposed, this was really helpful. And yeah, using array pointers looks a bit complicated to me at a glimpse, but I will get back to it later! – argeus Oct 05 '22 at 18:51

2 Answers2

1
  1. You do not have a 2D array only an array of pointers. You can have real 2D if you use array pointers.
  2. 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;
}
0___________
  • 60,014
  • 4
  • 34
  • 74
0

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.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335