How to Make a dynamic memory that is contigeous

I have a homework,I need a dynamic memory allocated to a pointer **p. and have the *p also dynamically allocated and the memory is contigeous to **p. Which means at the end of **p, *p is next in line.

I wrote this code: But I checked it and it is not contigeous. *SecondaryPntr has address pointing to the memory that is dynamically created so technically it is not contigeous.

I tried to move the memory:
memcpy(secondaryPntr, *secondaryPntr, rows * cols * sizeof(Type));

but it does not appear to work.

Is there anybody out there who can do it? I mean allocating a continous memory on **p, *p

Type **Create2D(size_t rows, size_t cols)
{

//variable declaration of pointers
Type **primaryPntr, **secondaryPntr;
//allocate memory just the primary
primaryPntr = (Type**) calloc(rows , sizeof(Type*));
//position the secondary pointer at the end of the primary
secondaryPntr = primaryPntr + rows;
//allocate another set of memory tack to the end of the primary.
*secondaryPntr = (Type*) calloc(rows * cols, sizeof(Type));
//Retuning the allocated memory from the beginning of the primaryPntr
//all the way to the end of the secondary pntr.
//memcpy(secondaryPntr, *secondaryPntr, rows * cols * sizeof(Type));
return ((primaryPntr + rows - 1) + (rows * cols * sizeof(Type) ));
}
to have a single contiguous block of memory, do a single allocation.

Only one call to malloc/calloc/what-have-you. The size of the allocation will be rows * cols * sizeof(Type) + rows * sizeof(Type*), if I understand you correctly.
Cubbi,

You understand me correctly. Your solution will work on malloc but how can you do it using calloc which has 2 parameters. I prefer a calloc solution so I could see how many bytes switched to zero when I dump the memory. If I use malloc there is no way for me to tell how many bytes are allocated just by looking on the dumped memory.
Thought I have the solution: but it still is not working.

Type **Create2D(size_t rows, size_t cols)
{
Type **primaryPntr, **secondaryPntr, **endPntr;
cols *= sizeof(Type);
primaryPntr = (Type**) malloc(rows * sizeof(Type*) + rows * cols);

for(endPntr = primaryPntr + rows, secondaryPntr = primaryPntr; secondaryPntr < endPntr; ++secondaryPntr)
{
*secondaryPntr = (Type*)(endPntr + rows * cols);
}
return(primaryPntr);
}

I still would like to use calloc but I can't figure out how to do it.
1
2
3
4
5
6
7
8
9
10
11
12
void* my_calloc(size_t size)
{
    void * ptr = malloc(size) ;
    memset(ptr, 0, size) ;
    return ptr ;
}

Type** Create2D( size_t rows, size_t cols )
{
    void * rawMemory = my_calloc(rows * sizeof(Type*) + rows*cols*sizeof(Type)) ;
    // ...
}


Your size calculation was wrong, and doesn't correspond to what Cubbi posted above. You do know this is a C++ forum right?

37 posts.. figure out the code tags! Look for the <> button.
I am aware that this is a C++ forum, and I am also aware that most C++ programmers started with C , so I am almost guaranteed people reading this know what I am talking about.

My calculation is correct, I think you just overlooked that the previous line of code before the calculation is "cols *= sizeof(Type)" so by the time the calculation is reach the "cols" is actually cols * sizeof(Type). Anyway if I used yours or mine both are correct.

But there is a problem that I overlooked. And I am not sure if you have overlooked it too.

The equation only works if sizeof(Type*) = sizeof(Type), if not the program crashes.
I would assume my professor knew this so he intentionally put a typedef making sizeof(Type*) != sizeof(Type). Prior to the function there is a typedef which put the sizeof(Type) = 9.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#define ELEMENTS 9
/* Type to use for dynamic array elements... */

//dont know what exactly this is doing but "Type" is a typedefinition of a char[9],  so if I say
// Type X, then X is an unsign char X[9].
typedef signed char Type[ELEMENTS];
#undef ELEMENTS

Type **Create2D(size_t rows, size_t cols)
{
    Type **primaryPntr, **secondaryPntr, **endPntr;
    int rowCount = 0; 
    primaryPntr = (Type**) malloc(rows * sizeof(Type*) + rows * cols * sizeof(Type));
    for(endPntr = primaryPntr + rows, secondaryPntr = primaryPntr; secondaryPntr < endPntr; secondaryPntr++)
    {        
        *secondaryPntr = (Type*)(endPntr + (rowCount * cols));
        rowCount++;
    }
    return(primaryPntr);
}


1. if you look on the equation it is composed of " (rows * sizeof(Type*) + rows * cols * sizeof(Type)) " a portion is (Type*) which is a pointer = 4 bytes and another portion is (Type) which according to typedef = 9 bytes.

2. If you look on line 16 of the code you will see that "rowCount * cols" is an offset starting from the pointer "endPntr" and by calculation the new pointer should be "endPntr + (offest by bytes equal to " rowCount * cols * sizeof(Type))".
but the compiler is offsetting it by " rowCount * cols * sizeof(Type*))".


My question now is how do I set line 16 so it will offset the endPntr by rowCount * cols * 9 instead of rowCount * cols * 4.
I am aware that this is a C++ forum, and I am also aware that most C++ programmers started with C


I think that's something some of us, including myself, aren't aware of, not having started with C. But that's really besides the point. You're more likely to get accurate responses on a forum dedicated to C (and fewer "this is the way it should be done in C++" responses) as well as not wasting the time of C++ forum viewers who expect to see C++ code.

My calculation is correct, I think you just overlooked


I did. I just skimmed over the unformatted mess and picked out the malloc line.

The equation only works if sizeof(Type*) = sizeof(Type), if not the program crashes.


The relative size of of Type* and Type isn't the cause of your problem.

*secondaryPntr = (Type*)(endPntr) + rowCount*cols ;

You want pointer arithmetic for a Type*, not a Type**.




Topic archived. No new replies allowed.