-1

EDIT: I should not use [].

I have defined integer N with value 5 and *malloc.

#define N

void* malloc (size_t size);

...

int *p_mat=(int*)malloc(sizeof(int*) * N);

This is the matrix.

Now we need the arrays.

int p_arr1=(int)malloc(sizeof(int) * 4);

int p_arr2=(int)malloc(sizeof(int) * 3);

int p_arr3=(int)malloc(sizeof(int) * 1);

int p_arr4=(int)malloc(sizeof(int) * 2);

int p_arr5=(int)malloc(sizeof(int) * 5);

So we have 5 arrays in different sizes. Now how do I make each pointer of the matrix point to the first cell in the array?

And another question, how do I send these variables to a function, I mean - what are the parameters in the function key?

Ofek .T.
  • 741
  • 3
  • 10
  • 29
  • 1. "how do I make each pointer of the matrix point to the first cell in the array" - they already do. 2 "what are the parameters in the function key" - WAT? 3. [Don't cast the return value of `malloc()`](http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc). 4. The size you pass to `malloc()` is wrong, it should be `sizeof(*p_mat)` instead. –  May 14 '13 at 12:47
  • I'm not sure I got to the end of your idea. 2. I meant that each cell in **p_mat will point to the first cell of each array – Ofek .T. May 14 '13 at 12:49
  • 3. I meant when I make a func. void print_number(int num); right? now how do I make a func that gets malloc – Ofek .T. May 14 '13 at 12:50

3 Answers3

3

An array of N pointers to arrays-of-integers of different sizes.... (Note don't cast malloc return value in C - can hide errors - see Do I cast the result of malloc?).

int i = 0;
int *p[N];
size_t sizes[] = { 4, 3, ..., 5 }; // N sizes

for(; i < N; ++i)
{
    p[i] = malloc(sizeof(int) * sizes[i]);
}

Now p is an array of pointers-to-int. p[n] is therefore the nth pointer-to-int in the array.

int *p[n] would look something like this in memory:

int *p[n]
+-----+
|     | <------- Each element of the array is a pointer-to-an-integer
|     |
+-----+
|     |
|     |
+-----+
.
.
.
+-----+
|     |
|     |
+-----+

When we then do p[n] = malloc(sizeof(int) * sizes[i]), we are saying that the pointer p[n] (remember each element of the array p is a pointer), points to a block of memory the size of sizes[i] integers. So you get something like...

+-----+                                            +------+------+ ... +------+
|p[n] |-------- array element is a pointer to ---> | int1 | int2 |     | intm |
|     |                                            |      |      |     |      |
+-----+                                            +------+------+ ... +------+
.
.
.
+-----+
|     |
|     |
+-----+

So when you write p[n] you are accessing a pointer to the array of ints you malloc()ed...

Later on in your code you must remember to free() the memory allocated :)

for(; i < N; ++i)
{
    free(p[i]);
}

Hope this helps...

EDIT: Didn't read the last bit of your question but wilsonmichaelpatrick has answered it...

EDIT: Note, btw, that I'm not checking malloc() return for NULL and handling the possible error a this is just an example...

If you do not want to declare int *p[N]; on the stack and would prefer the heap, try the following...

int i = 0;
size_t sizes[] = { 4, 3, ..., 5 }; // N sizes
int **p = malloc(sizeof(int *) * N);
for(; i < N; ++i)
{
    p[i] = malloc( sizeof(int) * sizes[i]);
}

...
...

for(; i < N; ++i)
{
    free(p[i]);
}

free(p);

EDIT: Use #include <stdlib.h> for definitions of free() and malloc()

Community
  • 1
  • 1
Jimbo
  • 4,352
  • 3
  • 27
  • 44
  • This is nice but it's ain't what I meant.I meant that I'll create a malloc and it will point to arrays – Ofek .T. May 14 '13 at 12:59
  • So do you want to replace `*p[N];` with int `**p = malloc(sizeof(int *) * N);`? – Jimbo May 14 '13 at 13:06
  • I think it's ok. but the free function is undefined – Ofek .T. May 14 '13 at 13:12
  • Are you doing a `#include `? That header file should define `malloc()` and `free()` for you... – Jimbo May 14 '13 at 13:13
  • I did: int sizes=(int)malloc(sizeof(int) * N); and free(sizes); And now it says 'int is imcopetible with (void)*' WHATTTTTTTT – Ofek .T. May 14 '13 at 13:19
  • malloc returns a **pointer**. You cast that pointer to an integer in your example. So free() will complain. The compiler is warning you that you are not trying to free a pointer... the types don't match :) `int` cannot be cast to `void *` without an explicit cast. Note however, that you *shouldn't* really be doing that anyway. Keep your pointers as pointers :) – Jimbo May 14 '13 at 13:32
  • Have updated the answer... hopefully this is more clear as to how pointers work :) – Jimbo May 14 '13 at 13:42
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/29924/discussion-between-jimbo-and-ofek-t) – Jimbo May 14 '13 at 14:08
2

EDIT: First, let's start with some corrections:

int **p_mat=(int**)malloc(sizeof(int*) * N);
int *p_arr1=(int*)malloc(sizeof(int) * 4);
int *p_arr2=(int*)malloc(sizeof(int) * 3);
int *p_arr3=(int*)malloc(sizeof(int) * 1);
int *p_arr4=(int*)malloc(sizeof(int) * 2);
int *p_arr5=(int*)malloc(sizeof(int) * 5);

Now, you can make each element of the matrix point to the first element of the array like this:

p_mat[0] = p_arr1;
p_mat[1] = p_arr2;
p_mat[2] = p_arr3;
p_mat[3] = p_arr4;
p_mat[4] = p_arr5;

Now if you want to pass this to a function, you can just have

int SomeFunction(int **theMatrix)
{
    /* Get third element of second row */
    int nSecondElementFirstRow = theMatrix[1][2]; /* same as p_arr2[2] above */
}

and call

SomeFunction(p_mat);

Specific to your comment, you could have a function:

void print_number(int n)
{
    printf("%d\n", n);
}

and call it like this:

 print_number(p_mat[1][2]);

to print out the third element of second row; that would print out p_arr2[2]. You could set p_arr2[2] = 12345; right after you malloc p_arr2 to test.

Finally, many comments I've just read suggest not casting the results of malloc as I have done: Do I cast the result of malloc?

Community
  • 1
  • 1
  • `int *p_mat` is a pointer to integer so I think `p_mat[0] = p_arr1` only works if `sizeof(int) == sizeof(int *)` and also isn't quire what is intended? `p_mat[0] = p_arr1` is trying to assign an integer to a pointer-to-integer. I suspect this would cause a compiler warning. – Jimbo May 14 '13 at 13:03
  • @Jimbo Yeah, I didn't see that, I just put a edit to correct that at the top, taking an educate guess at what the poster intended. Thanks though, good eye. –  May 14 '13 at 13:04
  • To the second answer: the function is yelling that it's doesn't **int it's (void)p_mat(int**) – Ofek .T. May 14 '13 at 13:16
  • @Ofek .T. Try `print_number(p_mat[1][2]);` if you're calling it from where you've malloc'ed p_mat. (I just edited that above, before I had it called from `SomeFunction`). Also make sure p_mat is `int**` not `int*` (it's in my corrections at the top). –  May 14 '13 at 13:24
1

If you want to associate each array to the first one:

p_mat[0] = p_arr1;
p_mat[1] = p_arr2;
//(...)
p_mat[4] = p_arr5;
Salem
  • 12,808
  • 4
  • 34
  • 54
  • Edited, question. +I can't use []. – Ofek .T. May 14 '13 at 12:56
  • And I get an error: 7 IntelliSense: a value of type "void (*)(int *p)" cannot be assigned to an entity of type "int" d:\users\user-pc\documents\visual studio 2010\projects\class 7\class 7\fml.c 23 – Ofek .T. May 14 '13 at 12:56
  • `int *p_mat` is a pointer to integer so I think `p_mat[0] = p_arr1` only works if `sizeof(int) == sizeof(int *)` and also isn't quire what is intended? `p_mat[0] = p_arr1` is trying to assign an integer to a pointer-to-integer. – Jimbo May 14 '13 at 13:04