# Re: Iterating trough a int **array. ANSI-C?

Discussion in 'C Programming' started by Matt Gregory, Aug 18, 2003.

1. ### Matt GregoryGuest

Tor Hildrum wrote:

> Imagine I have:
> int **array;
>
> array = malloc(n * sizeof(int *);
>
> for(i=0;i>n:++i)
> {
> array = malloc(n * sizeof(int));
> }
>
> Then fill it with values.
>
> Then I want a function that takes the address of the first
> element and number of elements to print out all elements.
>
> void print2darray(int *array, int n)
> {
> int i;
>
> for(i = 0; i < n; ++i)
> {
> printf("%d ", *array++); /* or array */
> }
> printf("\n");
> }
>
> I'm guessing the behaviour isn't defined?
> Is there a better/correct way to do this?

You need two loops, one for the rows and one for the columns

int i,j;
for (i=0; i<n; ++i) {
for (j=0; j<n; ++j)
printf("%d ", array[j]);
printf("\n");
}

Oh, you need to pass a **array to print2darray, too.

Matt Gregory, Aug 18, 2003

2. ### Tor HildrumGuest

Matt Gregory wrote:
>
>
> You need two loops, one for the rows and one for the columns
>
> int i,j;
> for (i=0; i<n; ++i) {
> for (j=0; j<n; ++j)
> printf("%d ", array[j]);
> printf("\n");
> }
>
> Oh, you need to pass a **array to print2darray, too.

The point is that I only want to pass the address to the first
element and the number of elements.

I guess the problem lies in the memory allocation.

array = malloc(n * sizeof array);

for( i = 0; i < n; ++i)
{
array = malloc(n * sizeof array);
}

ie the memory isn't contigous.

It's more of a curiosity than a real world problem.

Hmhm, would something like this do the trick?
for( i = 0; i < n; ++i)
{
if( i > 0)
{
array = malloc(1 * sizeof(int *));
}
else
{
array = realloc( (i+1) * sizeof(int *));
}

array = malloc(n * sizeof(int));
}

Tor

Tor Hildrum, Aug 18, 2003

3. ### Matt GregoryGuest

Tor Hildrum wrote:

> Matt Gregory wrote:
>
>>
>>
>> You need two loops, one for the rows and one for the columns
>>
>> int i,j;
>> for (i=0; i<n; ++i) {
>> for (j=0; j<n; ++j)
>> printf("%d ", array[j]);
>> printf("\n");
>> }
>>
>> Oh, you need to pass a **array to print2darray, too.

>
>
> The point is that I only want to pass the address to the first
> element and the number of elements.
>
> I guess the problem lies in the memory allocation.
>
> array = malloc(n * sizeof array);
>
> for( i = 0; i < n; ++i)
> {
> array = malloc(n * sizeof array);
> }
>
> ie the memory isn't contigous.
>
> It's more of a curiosity than a real world problem.
>
> Hmhm, would something like this do the trick?
> for( i = 0; i < n; ++i)
> {
> if( i > 0)
> {
> array = malloc(1 * sizeof(int *));
> }
> else
> {
> array = realloc( (i+1) * sizeof(int *));
> }
>
> array = malloc(n * sizeof(int));
> }

I'm not sure what you're talking about. This:

void print2darray(int **array, int n)
{
int i, j;
for (i = 0; i < n; ++i)
{
for (j = 0; j < n; ++j)
{
printf("%d ", array[j]);
}
printf("\n");
}
}

will print out this:

> array = malloc(n * sizeof array);
>
> for( i = 0; i < n; ++i)
> {
> array = malloc(n * sizeof array);
> }

If you want a contiguous block of memory, just allocate
like:

int *array = malloc(n * n * sizeof(int));

and define the print function like:

void print2darray(int *array, int n)
{
int i, j;
for (i = 0; i < n; ++i)
{
for (j = 0; j < n; ++j)
{
printf("%d ", array[i * n + j]);
}
printf("\n");
}
}

I'm pretty sure that will work.

Matt Gregory, Aug 18, 2003
4. ### Tor HildrumGuest

Matt Gregory wrote:

> If you want a contiguous block of memory, just allocate
> like:
>
> int *array = malloc(n * n * sizeof(int));
>
> and define the print function like:
>
> void print2darray(int *array, int n)
> {
> int i, j;
> for (i = 0; i < n; ++i)
> {
> for (j = 0; j < n; ++j)
> {
> printf("%d ", array[i * n + j]);
> }
> printf("\n");
> }
> }
>
> I'm pretty sure that will work.

Yup, but the problem is:
You have a pointer to pointer to int(**array) and the number of elements.

You have a function that takes the address of the first element
in **array and the number of elements.

Basically, how can you allocate **array so that you can iterate trough it
using only the address of the first element and the number of elements.

As I said, this is more of a curiosity than a real world problem.

nikon

Tor Hildrum, Aug 18, 2003
5. ### Kevin EastonGuest

Tor Hildrum <> wrote:
> Matt Gregory wrote:
>
>> If you want a contiguous block of memory, just allocate
>> like:
>>
>> int *array = malloc(n * n * sizeof(int));
>>
>> and define the print function like:
>>
>> void print2darray(int *array, int n)
>> {
>> int i, j;
>> for (i = 0; i < n; ++i)
>> {
>> for (j = 0; j < n; ++j)
>> {
>> printf("%d ", array[i * n + j]);
>> }
>> printf("\n");
>> }
>> }
>>
>> I'm pretty sure that will work.

>
> Yup, but the problem is:
> You have a pointer to pointer to int(**array) and the number of elements.
>
> You have a function that takes the address of the first element
> in **array and the number of elements.
>
> Basically, how can you allocate **array so that you can iterate trough it
> using only the address of the first element and the number of elements.
>
> As I said, this is more of a curiosity than a real world problem.

A discussion on this, including the method you're looking for, is in the
FAQ. It's a worthwhile read. Briefly:

int *whole_array;
int **array;
int i;

whole_array = malloc(rows * cols * sizeof *whole_array);
if (!whole_array)
return;

array = malloc(rows * sizeof *array);
if (!array) {
free(whole_array);
return;
}

for (i = 0; i < rows; i++) {
array = whole_array + i * cols;
}

You can rewrite it without the whole_array temp if you want - array[0]
has its value.

- Kevin.

Kevin Easton, Aug 18, 2003
6. ### Kevin EastonGuest

Brett Frankenberger <> wrote:
> In article <cyX%a.23579\$KF1.317964@amstwist00>,
> Tor Hildrum <> wrote:
>>
>>Basically, how can you allocate **array so that you can iterate trough it
>>using only the address of the first element and the number of elements.

>
> int **array;
>
> array = malloc(n * sizeof(int *);
>
> array[0] = malloc (n * n * sizeof (int));
> for(i=1;i>n:++i)

There's two mistakes on that line. ITYM:
for (i = 1; i < n; i++)

- Kevin.

Kevin Easton, Aug 18, 2003